Overwrite constructor in Java final class - java

I need to overwrite a constructor of a final class in Java. I know this isn't ideal, but it's unfortunately necessay. Is there any clever workaround to be able to achieve this? Specifically, there is a method that is called from inside the constructor in the final class, where I need to call with a different parameter (now it is called with a constant defined in the package of the final class).

It isn't just not ideal, it's not possible because it is final. Your best option would be to create a wrapper class:
class WrapperClass {
private FinalClass finalClass;
public WrapperClass() {
finalClass = new FinalClass();
}
public void doStuff() {
finalClass.doStuff(); // <- this would be the final method you want to override
// Do your own stuff
}
}

There is no good trick to circumvent final methods, but there is a good trick against (static or not) final fields. If changing that constant you talked about is an option, then you can do that by using reflection:
private static void setDefault(String newDefault) throws Exception {
Field staticField = SomeFinalClass.class.getDeclaredField("CONSTANT");
setValue(null, staticField, newDefault);
}
protected static void setValue(Object owner, Field field, Object value) throws Exception {
makeModifiable(field);
field.set(owner, value);
}
/**
* Force the field to be modifiable and accessible.
*/
protected static void makeModifiable(Field nameField) throws Exception {
nameField.setAccessible(true);
int modifiers = nameField.getModifiers();
Field modifierField = nameField.getClass().getDeclaredField("modifiers");
modifiers = modifiers & ~Modifier.FINAL;
modifierField.setAccessible(true);
modifierField.setInt(nameField, modifiers);
}
}
Note: obviously such a trick should be handled with care and avoided if there is a regular design pattern available.

If the class you want to modify has an interface, you can use java.lang.reflect.Proxy:
public class ProxyTest {
#Test
public void proxy() throws Throwable {
InvocationHandler handler = new MyInvocationHandler(new MyClass());
MyInterface f = (MyInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(),
new Class[] { MyInterface.class },
handler);
int result = f.test();
assertThat(result).isEqualTo(20);
}
}
class MyInvocationHandler implements InvocationHandler {
private MyInterface wrappedInstance;
public MyInvocationHandler(MyInterface object) {
this.wrappedInstance = object;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("test")){
return 20;
} else {
return method.invoke(this.wrappedInstance, args);
}
}
}

Related

Java Reflection: Why getConstructors() for class A returns an empty array? [duplicate]

I can't seem to use getConstructor for constructors with no parameters.
I keep getting the following exception:
java.lang.NoSuchMethodException: classname.<init>()
Here is the code:
interface InfoInterface {
String getClassName();
String getMethodName();
String getArgument();
}
class asa implements InfoInterface {
#Override
public String getClassName() {
return ("jeden");
}
#Override
public String getMethodName() {
return ("metoda");
}
#Override
public String getArgument() {
return ("krzyk");
}
}
class Jeden {
Jeden() {
System.out.println("konstruktor");
}
public void Metoda(String s) {
System.out.println(s);
}
}
class Start {
public static void main(String[] argv) {
if (argv.length == 0) {
System.err.println("Uzycie programu: java Start nazwa_klasy nazwa_klasy2...");
return;
}
try {
for (int x = 0; x < argv.length; x++) {
Class<?> c = Class.forName(argv[x]);
InfoInterface d = (InfoInterface) c.newInstance();
String klasa = d.getClassName();
String metoda = d.getMethodName();
String argument = d.getArgument();
Class<?> o = Class.forName(klasa);
// o.newInstance();
Constructor<?> oCon = o.getConstructor();
System.out.println("ASD");
Class<?> p = (Class<?>) oCon.newInstance();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
o.newInstance(); prints "konstruktor" without problems.
The problem is clear when you read the javadoc of .getConstructor():
Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.
Emphasis mine.
In your code, the constructor is not public!
Example:
// Note: class is NOT public -- its default constructor won't be either
final class Test
{
public static void main(final String... args)
throws NoSuchMethodException
{
// throws NoSuchMethodException
Test.class.getConstructor();
}
}
Obligatory link to an SO answer which also gives the JLS reference. In particular, note that the default constructor has the same access modifier as the class.
It seems as if your class provides a constructor that is NOT a default constructor. The call to getConstructor() without parameters requires the class to have a default constructor. The following test illustrates this.
import org.junit.Test;
public class ConstructorTest {
public static class ClassWithParameterizedConstructor {
public ClassWithParameterizedConstructor(final String param) {
// A parameterized constructor, no default constructor exists
}
}
#Test
public void testFoo() throws NoSuchMethodException {
// Parameterized constructor lookup works fine
ClassWithParameterizedConstructor.class.getConstructor(String.class);
// This doesn't work since there is no default constructor
ClassWithParameterizedConstructor.class.getConstructor();
}
}
So, a possible solution is to either change the call to getConstructor() to include the correct type or to provide a default constructor on the object itself (but why would you do that?).
Read this: http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html
It seems that both classes Class and Constructor have the method newInstance the difference is that in the Class class you can only call newInstance with no arguments, so the called constructor must have an no arguments (this also brings a problem when you have more that one constructor).
The methoe newInstance in the Constructor class allows you to call the constructor with arguments also, notice that you can also use the method getConstructors instead of getConstructor that returns you all the class constructors and allows you to call the constructor method you want.
In this case, since you only have one constructor only and with no arguments, Class.newInstance works fine. To use the getConstructor to have the same result you'll need to add in the end oCon.newInstance();
You can use getDeclaredConstructors() which returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object
class SomeClass{
{
System.out.println("I'am here!");
}
}
public class Main {
public static void main(String[] args) throws Exception{
System.out.println(Arrays.toString(SomeClass.class.getDeclaredConstructors()));
// returns public, protected, default (package) access, and private constructors
// System.out.println(SomeClass.class.getConstructor());
// in that case you got:
// NoSuchMethodException: reflection.SomeClass.<init>()
// because SomeClass don't have public constructor
for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
constructor.newInstance();
}
}
}
And if you have private constructor like this:
class SomeClass{
private SomeClass(String val){
System.out.println(val);
}
}
You have to set accessible for constructor:
constructor.setAccessible(true);
And get something like this:
class SomeClass{
private SomeClass(String val){
System.out.println(val);
}
}
public class Main {
public static void main(String[] args) throws Exception{
for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
// constructor.newInstance("some arg"); // java.lang.IllegalAccessException
constructor.setAccessible(true);
constructor.newInstance("some arg");
}
}
}
Note: if your class declared as private his default constructor must be private too.
And be careful with nonstatic-inner classes, which receives an outer class instance
In this (somewhat convoluted) scenario, it's actually possible to get hold of the (non-public) constructor by replacing:
Constructor<?> oCon = o.getConstructor();
with
Constructor<?> oCon = o.getDeclaredConstructor();
The "default" visibility of the Jeden class (and its constructor) makes it accessible to the Start class, since it's defined in the same package.

Constructor, subclass method called from base and instance member order initialization problem [duplicate]

This question already has answers here:
Initialize field before super constructor runs?
(7 answers)
Closed 4 years ago.
So, I'm trying to design a small base abstract class:
public abstract class BaseClass
{
abstract void reload();
protected BaseClass()
{
reload();
// schedule reload for every X minutes
}
}
Now, subclass:
class SubClass extends BaseClass
{
private int member = 5;
#Override
void reload()
{
member = 20;
}
}
Now, the problem I'm facing is that reload() method is called before the member is initialized. Thus, member is assigned 20 and afterwards, assigned with the value 5. (this is only an example of course, the actual code is different, but the same idea).
What is the best design for what I'm trying to achieve?
I want the order of the initialization to be - member assigned 5, and if reload() fails for some reason i want it to stay with the initial value. However in this code, 5 overrides the value of reload(). If I don't assign an initial value for the instance member, it works of course.
Is it possible what I'm asking?
Override the constructor and call reload() there but do not call super(), this might not be acceptable for other reasons :)
class SubClass {
private int member = 5;
public SubClass() {
reload();
}
...
}
You can use a builder to achieve that.
This way you can achieve full control.
public abstract class Foo {
public abstract void postConstruct();
public static void main(String[] args) {
Bar bar = Foo.build(Bar.class);
System.out.println(bar);
}
public static <T extends Foo> T build(Class<T> clazz) {
T obj;
try {
obj = clazz.newInstance();
obj.postConstruct();
return obj;
} catch (Exception e) {
throw new IllegalArgumentException(
"Class "+clazz.getName()+" is not a valid class",e);
}
}
}
public class Bar extends Foo {
int value = 10;
protected Bar() {
super();
}
public void postConstruct() {
value = 7;
}
#Override
public String toString() {
return "Bar [value=" + value + "]";
}
}

java member method initializer pattern to what extent this design is correct bug safe and suggestions to improve it

to avoid the overridable method call in constructor dilemma this approache delegate the variables initialization and calls to overridable methods to a member method that return reference to the instance its self and exception to be thrown if trying to use instance without invoking the initialization method/s so that the creation of objects will look like this
SuperClass sup = new SuperClass().initialize("big");
SubClass sub = new SubClass().initialize("sato", "try initialzer");
SubClass sub2 = new SubClass().initialize("happy");
SubClass sub3 = new SubClass().initialize();
my super class should implement methods of initializable interface it has two methods
1) initialize method in which i write code to do the following in order
a) call setter methods and other initialization code
b) make call to overridable method putting them at end of the method
this method can be overloaded to provide versions of it with necessary arguments as illustrated in complex example
2) isInitialzed method to check if the initialization done or not when a call to a method in my class that reference a variable that is initialized in initialize method and initialization not done i throw my NonInitializedInstanceException
the subclass should override the initialize method/s "all the super class versions of the initialize method" and do the following in order
1)initialize its variables
2)can call super method that don't throw NonInitializedInstanceException
3)call super.initialize() method
4)call setter methods "note that the super call the setters so to avoid our setter been useless we should call it after super initialize method call"
5)can call super method that throw NonInitializedInstanceException
handling overloaded versions of initialize done by calling the one with more parameters from the less parameter one
the following are my code
the interface
/**
* #author ahmed mazher
* #param <T> making class initializable
*
*/
public interface Initializable<T> {
/**
* do the initialization job and return reference to the implementing
* class current instance
* #return
*/
T initialize();
/**
* test the variables that you initialize in the initialize method
* if it was initialized or not "or what ever test you see appropriate"
* #return
*/
boolean isInitialized();
}
the NonInitializedInstanceException class
/**
* #author Ahmed mazher
* runtime exception to be thrown by method that reference variables that
* are initialized by the initialize method of the initializable interface
* you can test if initialization was done or not by isInialized method
* of the same interface if false throw the exception
*/
public class NonInitializedInstanceException extends RuntimeException {
private static final long serialVersionUID = 1L;
#Override
public String getMessage() {
return super.getMessage()
+ " you must call instance.initialize() method "
+ "before calling this method";
}
}
example of using them
/**
* #author ahmed mazher
* testing the initializer pattern
*/
class LearnJava {
public static void main(String args[]) {
SuperClass sup = new SuperClass().initialize();
SubClass sub = new SubClass().initialize();
}
}
class SuperClass implements Initializable<SuperClass> {
private String initializeDependentName;
private final String nonInitializeDependentVal = "well done";
#Override
public SuperClass initialize() {
//initializing super Class fields
setInitializeDependentName("super class");
//overidable method call in initializer "replacement of
//call in constructor"
overridablePrintName();
return this;
}
public final String getInitializeDependentName() throws NonInitializedInstanceException {
if (!isInitialized()) {
throw new NonInitializedInstanceException();
}
return initializeDependentName;
}
public final void setInitializeDependentName(String initializeDependentName) {
this.initializeDependentName = initializeDependentName;
}
public final void youCanCallMeBeforeInitialization(){
System.out.println(nonInitializeDependentVal);
}
public void overridablePrintName() {
System.out.println("I'm the super method and my name is " + getInitializeDependentName());
}
#Override
public boolean isInitialized() {
return initializeDependentName != null;
}
//to avoid some one messing with isInitialized() make your
//private one and use it instead but don't forget to call it inside
//the body of isInitialized() to maintian integrity of inheritance hierarchy
// private boolean privateIsInitialized(){
// return initializeDependentName != null;
// }
// #Override
// public boolean isInitialized() {
// return privateIsInitialized();
// }
}
class SubClass extends SuperClass {
private String job;
#Override
public SubClass initialize() {
//initializing subClass fields
setJob("testing initialize method");
//call super method that throws nonInitialiezinstanceException
//before call super.initialize() method will rise the exception
//unless you overided the isInitialized method "welling to take the risk"
//------------------------------------------------------------------
//System.out.println(getName().toUpperCase());
//------------------------------------------------------------------
//call super method that not throws nonInitialiezinstanceException
//before call super.initialize() method
youCanCallMeBeforeInitialization();
setInitializeDependentName("subClass");
//calling super.initialize() method initialize super methods
super.initialize();//initialize the super class
//call super method that throws nonInitialiezinstanceException
//after call super.initialize() method will not rise the exception
//unless you overided the isInitialized method in stupid way ^_^
System.out.println(getInitializeDependentName().toUpperCase());
//calling the setter method now to change my property as calling
//it before the super initialization is useless as the super
//initialization will erase it
setInitializeDependentName("subClass");
System.out.println(getInitializeDependentName().toUpperCase());
return this;
}
public final void setJob(String job) {
this.job = job;
}
#Override
public void overridablePrintName() {
System.out.println("i'm overriden method and i do " + job);
}
#Override
public boolean isInitialized() {
//return false;//stupid version
//return true;//take the risk
return job != null && super.isInitialized();//a good one
}
}
a more complicated example using initializer with arguments
class LearnJava {
public static void main(String args[]) {
SuperClass sup = new SuperClass().initialize("big");
SubClass sub = new SubClass().initialize("sato", "try initializer");
SubClass sub2 = new SubClass().initialize("happy");
SubClass sub3 = new SubClass().initialize();
}
}
class SuperClass implements Initializable<SuperClass> {
private String initializeDependentName;
private final String nonInitializeDependentVal = "well done";
#Override
public SuperClass initialize() {
return initialize("i'm super with no name");
}
public SuperClass initialize(String name) {
//initializing super Class fields
setInitializeDependentName(name);
//overidable method call in initializer "replacement of
//call in constructor"
overridablePrintName();
return this;
}
public final String getInitializeDependentName() throws NonInitializedInstanceException {
if (!isInitialized()) {
throw new NonInitializedInstanceException();
}
return initializeDependentName;
}
public final void setInitializeDependentName(String initializeDependentName) {
this.initializeDependentName = initializeDependentName;
}
public final void youCanCallMeBeforeInitialization() {
System.out.println(nonInitializeDependentVal);
}
public void overridablePrintName() {
System.out.println("i'm the super method my name is " + getInitializeDependentName());
}
#Override
public boolean isInitialized() {
return initializeDependentName != null;
}
//to avoid some one messing with isInitialized() make your
//private one and use it instead but don't forget to call it inside
//the body of isInitialized() to maintian integrity of inheritance hierarchy
// private boolean privateIsInitialized(){
// return initializeDependentName != null;
// }
// #Override
// public boolean isInitialized() {
// return privateIsInitialized();
// }
}
class SubClass extends SuperClass {
private String job;
#Override
public SubClass initialize() {
return initialize("i'm subclass no one give me name");
}
#Override
public SubClass initialize(String name) {
return initialize(name, "no one give me job");
}
public SubClass initialize(String name, String job) {
//initializing subClass fields
setJob(job);
//call super method that throws nonInitialiezinstanceException
//before call super.initialize() method will rise the exception
//unless you overided the isInitialized method "welling to take the risk"
//------------------------------------------------------------------
//System.out.println(getName().toUpperCase());
//------------------------------------------------------------------
//call super method that not throws nonInitialiezinstanceException
//before call super.initialize() method
youCanCallMeBeforeInitialization();
//calling super.initialize() method initialize super methods
super.initialize(name);//initialize the super class
//call super method that throws nonInitialiezinstanceException
//after call super.initialize() method will not rise the exception
//unless you overided the isInitialized method in stuped way ^_^
System.out.println(getInitializeDependentName().toUpperCase());
//calling the setter method now to change my property as calling
//it before the super initialization is useless as the super
//initialization will erase it
setInitializeDependentName("setter called in subclass");
System.out.println(getInitializeDependentName().toUpperCase());
return this;
}
public final void setJob(String job) {
this.job = job;
}
#Override
public void overridablePrintName() {
System.out.println("i'm overiden method my name is "
+ getInitializeDependentName()
+ " and i do " + job);
}
#Override
public boolean isInitialized() {
//return false;//stuped version
//return true;//take the risk
return job != null && super.isInitialized();//a good one
}
}
suggestion of using static method factory pattern and as i expected static pain never ends here is my trial to adapt my pattern into static one but i failed i don't know how to make subClass invoke superClass create method to affect its instance
class LearnJava {
public static void main(String args[]) {
SuperClass.create("nono");
SubClass.create("sato","test factory");
}
}
class SuperClass{
private String name;
protected SuperClass() {
}
public static SuperClass create(String name) {
SuperClass sup = new SuperClass();
//initializing super Class fields
sup.setName(name);
//overidable method call useless as i always call the super instance version
sup.overridablePrintName();
return sup;
}
public final String getName(){
return name;
}
public final void setName(String name) {
this.name = name;
}
public void overridablePrintName() {
System.out.println("i'm the super method my name is " + getName());
}
}
class SubClass extends SuperClass {
private String job;
protected SubClass() {
super();
}
public static SubClass create(String name, String job) {
SubClass sub = new SubClass();
//initializing subClass fields
sub.setJob(job);
//call the super class initializer to affect this sub class instatnce
//seems no way to do it
sub.create(name);
SubClass.create(name);
SuperClass.create(name);
return sub;
}
public final void setJob(String job) {
this.job = job;
}
#Override
public void overridablePrintName() {
System.out.println("i'm overiden method my name is "
+ getName()
+ " and i do " + job);
}
}
i hope it be a good idea waiting for your comments and suggestions
It's a good idea to look for some initialization methods which will provide you some good structure and high quality code but I think you may refer to the Factory Method Pattern so you can improve what you have done already
The factory method pattern is a way to encapsulate object creation.
Without a factory method, you would simply call the class's
constructor directly: Foo x = new Foo(). With this pattern, you would
instead call the factory method: Foo x = Foo.create(). The
constructors are marked private, so they cannot be called except from
inside the class, and the factory method is marked as static so that
it can be called without first having an object.

Workaround to accessing non-static member method from a static inner class

I have this non-static inner class that causes memory leaks, because it holds an implicit reference to the enclosing class:
private class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub {
#Override
public void onScheduleUpdatedEvent() throws RemoteException {
updateCalendar();
}
}
In order to stop it from leaking, I need to make it static:
private static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub {
#Override
public void onScheduleUpdatedEvent() throws RemoteException {
updateCalendar();-> Compiler error - trying to access a non-static...
}
}
It is impossible to make updateCalendar() static because in it I access other non-static variables and it becomes a mess. What do I do?
You need to pass in a reference to an instance of your outer class. And you need to make your static class public.
public static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub {
#Override
public void onScheduleUpdatedEvent(final TheOuterClass instance) throws RemoteException {
instance.updateCalendar();
}
}
private static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub {
final WeakReference<Object> obj; //change <Object> to whatever type it is.
CalendarScheduleUpdatedEventListener(Object x) {
this.obj = new WeakReference<>(x);
}
#Override
public void onScheduleUpdatedEvent() throws RemoteException {
Object o = obj.get();
if (o == null) {
//because a WeakReference will be null if it has been garbage collected.
return; //or throw some exception
}
o.updateCalendar();
}
}

Can I access new methods in anonymous inner class with some syntax?

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

Categories

Resources