I have the capability to extend a class at compile time, but I need to be able to create an instance of this subclass at runtime using an instance of the superclass that was already instantiated.
This should be possible in theory because superclass constructors are already called before the subclass constructor.
I do not have access to the program sufficiently to change the instantiation to my subclass nor to interrupt the original instantiation.
Use Case: There is an existing array of instances of class X. My code is loaded in after. I need to override one of the methods of one of the instances X with my loaded subclass Y extends X. The parent program accesses the objects only through that array, so I want to replace that array element with my Y instance, but it needs to behave as if it were instantiated originally into that array. I cannot just enclose the superclass instance and forward calls, and there are difficult complications with reinstantiating the superclass.
I hope that is more clear.
To reiterate what you are trying to do..
Within the JVM, there exists an instance of ClassA. You would like to dynamically modify the class heiarchy of ClassA, such that a new class exists called ClassB which derives from ClassA. Then you would like to instantiate an instance of ClassB but have it's subclass implementation be that of the existing instance of ClassA. Something like a memory replacement.
You might want to look into http://www.jboss.org/javassist . What you would need to do is replace the ClassLoader, then determine when ClassA is being loaded, then instantiated. You'd then need to construct ClassB and return that instead.
Update
After a little more research there is still the possibility you can do what you want. IDE's like Eclipse support HotSwap'ing method implementations while debugging. They use the Instrumentation API.
http://zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/
You can replace method bodies but not add or remove methods themselves. So while you won't be able to change the type to your new type, you can completely replace the method implementation with your new implementation.
I would suggest using cglib:
cglib is a powerful, high performance and quality Code Generation
Library, It is used to extend JAVA classes and implements interfaces
at runtime
You may find some examples here:
https://github.com/cglib/cglib/wiki
Have you looked at Java Proxies?
Here is a snippet from Javadoc:
"A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created"
I don't know if it's a sollution but if you have
public static Foo foo = new Foo();
and you want to replace it with Bar which extends Foo
make Bar an Wrapper for of Foo and use reflection to let foo point to your Bar instance.
public class Foo extends Bar {
private bar;
public Foo(Bar oldInstance) {
this.bar = oldInstance;
}
}
and
// exception handling ommitted
public static void onStartup() {
Class fooRefClass = FooRef.class;
Field fooRef = fooRefClass.getDeclaredField("foo");
Foo foo = (Foo)fooRef.get(null);
Bar bar = new Bar(foo);
fooRef.set(null, bar);
}
As told I don't know if this is possible in your case.
Related
Suppose I have these classes:
public class ChildClass extends ParentClass
{
// some class definition here
}
public abstract class ParentClass
{
public static void printClass()
{
// get the class that extends this one (and for example, print it)
}
// some class definition here
}
Lets say when calling ParentClass.printClass() I want to print the name of the class (like doing System.out.println(ParentClass.class)). When then extending ParentClass (for example like in ChildClass) and calling ChildClass.printClass(), I want it to print the name of the extending class (like doing System.out.println(ChildClass.class)). Is this somehow possible?
I've found a way to get the class from inside a static method by using MethodHandles.lookup().lookupClass(), but when using it inside of ParentClass.printClass and extending ParentClass, then calling printClass on the extending Class, I always get the class of ParentClass.
static methods are best thought of as living entirely outside of the class itself. The reason they do show up in classes is because of the design of java (the language) itself: Types aren't just types with a hierarchy, they also serve as the primary vehicle for java's namespacing system.
Types live in packages, packages are the top level namespace concept for types. So how do you refer to a method? There's only one way: Via the type system. Hence, static methods do have to be placed inside a type. But that's about where it ends.
They do not inherit, at all. When you write:
ChildClass.lookupClass()
The compiler just figures out: Right, well, you are clearly referring to the lookupClass() method in ParentClass so that is what I will compile. You can see this in action yourself by running javap -c -p MyExample. The same principle applies to non-static methods, even.
For instance methods, the runtime undoes this maneuvre: Whenever you invoke a method on any object, the runtime system will always perform dynamic dispatch; you can't opt out of this. You may write:
AbstractList<String> list = new ArrayList<String>();
list.sort(someComparator);
and you can use javap to verify that this will end up writing into the class file that the method AbstractList::sort is invoked. But, at runtime the JVM will always check what list is actually pointing at - it's an instance of ArrayList, not AbstractList (that's obvious: AbstractList is abstract; no object can ever be directly instantiated as `new AbstractList). If ArrayList has its own take on the sort method, then that will be called.
The key takeaway of all that is: Static methods do not inherit, therefore, this dynamic dispatch system is not available to them, therefore, what you want cannot be done in that fashion.
So what to do?
It feels like what you're doing is attempting to associate a hierarchy to properties that apply to the class itself. In other words, that you want there to be a hierarchical relationship between the notion of 'ParentClass's lookupClass method and ChildClass's lookupClass method - lookupClass is not a thing you ask an instance of ChildClass or ParentClass - you ask it at the notion of the these types themselves.
If you think about it for a moment, constructors are the same way. You don't 'ask' an instance of ArrayList for a new arraylist. You ask ArrayList, the concept. Both 'do not really do' inheritance and cannot be abstracted into a type hierarchy.
This is where factory classes come in.
Factory classes as a concept are just 'hierarchicalizing' staticness, by removing static from it: Create a sibling type to your class hierarchy (ParentClassFactory for example):
abstract class ParentClassFactory {
abstract ParentClass create();
abstract void printClass();
}
and then, in tandem with writing ChildClass, you also write ChildClassFactory. Generally factories have just one instance - you may want to employ the singleton pattern for this. Now you can do it just fine:
class ChildClassFactory extends ParentClassFactory {
private static final ChildClassFactory INSTANCE = new ChildClassFactory();
public static ChildClassFactory instance() { return INSTANCE; }
public ParentClass create() { return new ChildClass(); }
public void printClass() { System.out.println(ChildClass.class); }
}
// elsewhere:
// actually gets the ChildClassFactory singleton:
ParentClassFactory factory = ....;
factory.printClass(); // will print ChildClass!
Quoting #RealSkeptic:
Static methods are not inherited. The fact that you can call ChildClass.printClass() is just syntactic sugar. It actually always calls ParentClass.printClass(). So you can't do something like that with a static method, only an inheritable non-static one.
Is it possible to inherit a class without using extends keyword in Java ?
Yes. Every class extends Object, whether you add extends Object to the declaration or not.
There are also anonymous classes, such as
Foo foo = new Foo(){
// some method implemented in here.
};
which can extend a class without extends.
Yes, Each class extend the Object by default without declaration.
As has been said on this thread all classes extend from Object.
So it does exist, however this is not something which you can control without using the extends keyword. I don't think that you will ever need to, if you do maybe we should discuss that specific situation.
This hasn't been covered in my course and I am having trouble thinking up a reason why would I want this. I've come across the code below:
OpenNetworking proxy = service.getPort(OpenNetworking.class);
In the above line I can see that it is returning the port and it is passing the class to the method but I read this as the OpenNetworking.class isn't instantiated yet. I'm obviously missing something.
This is an example of a Factory method pattern.
The class type is provided to the service to give a Port on the specified type OpenNetworking.
A class type, in this case, is handy as it is a simplest way to provide a unique identifier to an object when doing object creation. It doesn't need to be maintained, should the state of the object changes as the class contains the type of the object.
There can be many reasons to do that:
Controlling number of instances of a class: Say you want to control how many instances you want for a class, you can make constructor
private or package level and return same instance when somebody calls
your method
Security: You might want your class to be secure and generally don't want to allow anybody to instantiate your class.
Dependency: Your class might have dependency which can be figured out only at runtime and then service class use reflection to
instantiate class appropriately.
Here we are passing the class type (Class in Java). So the treatment in the method getPort is done based on the Type of Class, we don't need an Object instance to handle it.
It is different, of course, than this code (whic doesn't compile):
OpenNetworking proxy = service.getPort(new OpenNetworking());
Also because of limitations of generics, when you have a generic class/method and you need to create a new instance, you will need a class. For example:
class SomeClass<T> {
public static<T> T create() {
return new T(); // will not work
}
public static<T> T create(Class<T> clazz) {
return clazz.newInstance(); //will work
}
}
so you need class instance to create a new object of that type.
Apparently the method service.getPort(); behaves according to the type in the parameter, imagin that there is a port for openNetworking and another one for closeNetworking, so providing the class name as a parameter would be enough to get the needed port number, one can create an enumeration for that but then extending existing code would force you to extend your enumeration too for each type.
The used method has this definition:
public <T> T getPort(Class<T> serviceEndpointInterface)
So it returns an instance of an object which extends the class T (a proxy,synthetic class instance)
Assume I obtained a Class object by loading a class dynamically using Class.forName("Foo"). Foo is abstract in this case, so I cannot call newInstance() on it. (How) is it possible to declare a concrete subclass of Foo?
You declare it as not abstract e.g.
class Bar extends Foo {
// implement methods are required.
}
In short, just because you loaded the class dynamically doesn't mean the rules change ;)
Foo is not available at compile-time
If you don't have Foo available at compile time, you still need to have a sub-class of this class which is concrete to create it. To do this you have two options.
find a concrete class and create that. You can use the Reflections library to find such a class.
generate code and compile it using the Compiler API, or BeanShell.
generate byte code for the subclass using ObjectWeb's ASM.
I suspect the first option is what you need because unless there is a subclass provided for you, you still need to generate the code for the abstract methods.
I want to pass an instance of a super class to a constructor of a sub class. My first idea was to swap the instance of the super class in the sub class similar to javascripts prototypes, but I was told here that Java does not support swapping the reference of the super instance because there is no super instance per se.
To circumvent this issue I want to use a copy constructur which accepts a super class instance. Then I will have to relink all references manually which on the long run will invite bugs when other people extend the code of the super class and forget the copy constructur in the sub class.
Question: Is there some neat and nice way to copy all references automatically, maybe with some reflection mechanism to prevent future bugs?
You shouldn't copy all the references from the superclass instance to the subclass instance. BTW, all these references should not even be accessible from the subclass, if they are declared as private fields in the superclass (as they should be, generally).
What you probably need is delegation, instead of inheritance:
// Foo is the superclass
private class FooAdapter {
private Foo foo;
public FooAdapter(Foo foo) {
this.foo = foo;
}
public void doThis() {
return foo.doThis();
}
}
FooAdapter could extend Foo or (better) theyr should implement a common interface, but that's not necessarily needed.
If this doesn't answer your problem, please tell us what you want to do, instead of telling us how you want to do it. What's the problem you want to solve?