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?
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.
I have an abstract class A
I have about 10 classes that extend A
Class A has one or two static methods and it makes sense that these are static, because they belong to the 10 classes, NOT instances of them. One static method e.g. is called getAllFromX, which gets all all instances of the class from X, whatever that may be, it may be a server, well it actually is, but it doesn't matter. So you see it makes sense these methods are static and are not bound to an instance.
At the same time class A has a NON-static abstract method, each subclass overrides this method (just returns a string). I cannot make it static because static methods cannot be overridden (...).
To summarize: abstract class A has a static method and a abstract non-static method, that is overriden by the subclasses. I cannot make the second method static because it must be overriden. On the otherhand I could make the first method non-static, but it would be very ugly and bad programming style, so I'll leave it that way.
The catch? The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Is the "easiest" way to use reflection to get this done? I mean...really?
Like e.g., I get the class the static method is in:
Class<?> cl=new Object(){}.getClass().getEnclosingClass(); (a hack I found here, thank god...)
I then use getConstructor to construct an object of this subclass.
And then I use this object to call the non-static method.
Really?? Can it not be done easier? I mean that is if I want to design my program conceptually correct...
Coming from C# I don't like that (and the type erasure thing). It is just ugly. Doable but ugly. And a big stumbling block, at least for beginners. EDIT: after reading it again, I'd add: /rant end. Sorry, but I actually care.
I think what you in fact need is the following:
public class A {
public static Set<A> getAllFromX() {
...
}
}
public class B extends A {
public static Set<B> getAllFromX() {
...
}
}
public class C extends A {
public static Set<C> getAllFromX() {
...
}
}
(Just as the valueOf() and values() methods in enums, which is redefined in every Enum subclass, because static methods can't be inherited)
In this case, each class has its own static method doing whatever it wants. But your question doesn't make much sense because it says:
The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Indeed, the static method is not inherited by the subclass. Static methods are never inherited. If you define a static method foo() in A, and call
B.foo();
the compiler doesn't refuse to compile it, but it translates it to
A.foo();
So, there's no way to do in foo() something that depends on the class on which foo() is called, since it's always A.
You can always use reflection to invoke a method using class name e.g.
Object objectX = ClassX.class.newInstance();
//get your method passing argument types as second param
Method method = ClassX.class.getDeclaredMethod("methodX", null);
//invoke your method passing arguments as second param
method.invoke(objectX, null);
Since you mentioned your static method doesn't use any instance but you are using reflection to get the instance hence I am really not sure, how does it fit in your requirement though.
I think making it as an implemented method (non-static) in your abstract class is a better choice. That way you implement it once but its available in in all your 10 extending classes.
I think your problem is one of larger design. A different object should be responsible for retrieving instances of A or its subclasses. As you can see, relying on a static method to be replaced by subclasses does not work well. Without knowing more about the problem domain, it's hard to give a good answer, but I would consider something similar to the Abstract Factory pattern.
Broadly speaking: Define an abstract class, AFactory, with a method Collection getInstances(). Extend AFactory for each of the concrete subclasses of A you need to return and implement that logic in the overridden getInstances() method as appropriate. You may also provide a static method on the abstract AFactory, getFactory(Class), to get the appropriate factory subtype at runtime.
I have a superclass like this which I expect alot of classes to inherit:
public abstract class Super {
protected Object myField; //Not used anywhere in this class
//a load more code here which does useful stuff
}
All these classes will need to use an instance of myField. However the superclass does not. Have I made a bad design decision somewhere?
Not necessarily. If all the subclasses need the same field for the same reason, then that's no different than providing any other common functionality in a base class. as your classes grow you may find that you add common functionality which uses this field (e.g. referencing it in an equals/hashCode method).
Now, if the field is of type Object and each sub-class shoves something completely different into it, i would consider that a code smell.
Well IMHO, a field should not be present in a class if it's not really used by that class. What it seems to me that you really want here is to have a base class that tells its subclasses "you should ALL have some way of keeping state for X but I (the base class) will not modify that X state, in which case you should make an abstract method in order to convey that message, something like this:
public abstract class Super {
protected abstract Object getMyField();
}
It's hard to say with such a vague description, but it would seem like you could do some generalization and push some common code up into your superclass. If your subclasses are doing something similar with the field then some commonality could be found (using template methods or strategies to handle subclass-specific differences), otherwise if every subclass is doing something different with it then what's the point of using a common field?
No, I don't think so. Abstract class serve that purpose (Have common functionality in base class and let subclass implement only specific required functionality).
So, if you don't use that field in class Super - why do you need it there?
Perhaps your super class would provide an interface to interact with this field in generic way, for example:
public abstract class Super<T> {
protected T myField;
public T getField() {
return myField;
}
}
public class Child extends Super<String> {
public Child( String label ) {
super.myField = label;
}
}
As stated in this tuturial
A protected field or method is accessible to the class itself, its subclasses, and classes in the same package.
This means that the protected fields have been designed precisely to have these characteristics.
Just on a lighter note The only thing common in your hirarchy is one field then you should get rid of abstract class and Create one Marker Interface.
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.
Ok so I know that you can't have an abstract static method, although I see this as a limitation personally. I also know that overriding static methods is useless because when I am dealing with say MyList<T extends ObjectWithId> and my object has an abstract class with a static method that gets overridden in it's subclasses, T doesn't exist at runtime so ObjectWithId's static method would be called instead of the subclass.
So here is what I have:
class PersistentList<T extends ObjectWithId> implements List<T>{
}
where ObjectWithId is:
abstract ObjectWithId{
public abstract long getId();
}
Now the issue is that my PersistentList is meant to be stored on hard disk, hence the name, and in reality will only store ids of objects it holds. Now when I want to implement the
#Override
public T get(int index) {
}
method of PersistentList, what I want is for my program to use the id it has stored for index and call a static method objectForId(long id) which would be implemented in each subclass of ObjectWithId. It can't be a instance method because there is no instance yet, the point is to load the instance from the hard disk using the id. So how should it be implemented? One option is to have ObjectWithId have a constructor ObjectWithId(long id) implemented in each subclass, but T doesn't exist at runtime so how would I instantiate it? I know I could pass Class<T> object in the constructor of PersistentList but I would prefer if the constructor did not have any arguments, but I don't think there is a way to get the class of T without explicitly passing it in right?
I hope this is a better explanation, sorry for the ambiguous question I started with.
While passing the Class<T> as a constructor argument, it does not really solves your problem. You then have access to the class, but to get access to the static method defined on the class you will have to use generics (unless somebody else knows a way to call a static method defined on a class from a Class object).
I would define a new generic interface which contains a generic method objectForID, something like
public interface ObjectRetriever<T>{
public T objectForID( long aID );
}
and adjust the constructor of the PersistentList to take such a ObjectRetriever instance as parameter. This ObjectRetriever can then be used to restore the objects based on their ID.
While it always seems easier to start out with static methods, I've found it to usually be beneficial to avoid static methods for just this reason, and to use instance methods by default.
The advantage to this is extensibility. Besides allowing for inheritance and avoiding the "limitations" you mentioned, it provides for extensibility - without needing to redesign things and change APIs later. For example, "this class does exactly what I need, but I wish I could change only this one portion of functionality". If there are static methods calling other static methods, there is no good way to do this. If all the methods are non-static - I can subclass that class and override only the portion of functionality required.
The other (somewhat-related) limitation to static methods is that they can't be used to implement interfaces.
In summary, I prefer to reserve static methods for "utility methods" where the function that they are performing is really clear-cut, and there isn't any feasible future reason why an alternative implementation would need to be provided.