I'm playing around with Java's Reflection. I have an abstract class Base
with a constructor.
abstract class Base {
public Base( String foo ) {
// do some magic
}
}
I have some further classes extending Base
. They don't contain much logic. I want to instantiate them with Base
's constructor, without having to write some proxy contructors in those derived classes. And of course, I want to instantiate those derived classes with Reflection. Say:
Class cls = SomeDerivedClass.class;
Constructor constr;
constr = cls.getConstructor( new Class[] { String.class } ); // will return null
Class clsBase = Base.class;
constr = clsBase.getConstructor( new Class[] { String.class } ); // ok
Base obj = (Base) constr.newInstance( new Object[] { "foo" } ); // will throw InstantiationException because it belongs to an abstract class
Any ideas, how I can instantiate a derived class with Base's constructor? Or must I declare those dumb proxy constructors?
Yes, an abstract class can have a constructor in Java. You can either explicitly provide a constructor to the abstract class or if you don't, the compiler will add a default constructor of no argument in the abstract class.
You can access a private constructor of a class via reflection and thus can instantiate it.
A constructor is used to initialize an object not to build the object. As we all know abstract classes also do have a constructor. So if we do not define any constructor inside the abstract class then JVM (Java Virtual Machine) will give a default constructor to the abstract class.
Yes, we can define a parameterized constructor in an abstract class.
A class does not inherit constructors from it parent. A class does not have it parents constructors (though it can call them) So you have to call the constructors the class has, not a constructor a super class has.
The default constructor only appears to do this because it calls the default constructor of the parent by default. If the parent doesn't have a default constructor, neither can its immediate children.
I'm afraid your subclasses won't even compile until you have an explicit constructor in them calling one of the super() constructors.
You cannot construct an abstract class without specifying all of the details that will make it "non-abstract".
That means in the example:
public abstract class Parent {
String name;
public Parent(String name) {
this.name = name;
}
abstract public String getName();
}
no amount of constructor manipulating via reflection will return a Parent-only class. You can however, return an "anonymous" class by specifying the abstract details at construction time, like so:
Parent parent = new Parent() {
public String getName() { return "Bob"; }
};
Remember, sub-classing also calls the parent constructor, even if you don't put the code in explicitly. A sub-class written like:
public class Child extends Parent {
public Child(String name) {
}
}
will look for a no arg constructor in the Parent
class. If it finds one, then it will be compiled into code equivalent to
public class Child extends Parent {
public Child(String name) {
super();
}
}
If it doesn't find a no argument constructor in the Parent
class, it will fail to compile until you explicitly specify the parent class construction with the super(name);
constructor call.
Another thing to remember, all classes are subclasses of Object
, so if you don't provide an extends SomeClass
like so:
public class JustMe {
}
The compiler conceputally "corrects" you code at compile time to:
public class JustMe extends Object {
public JustMe() {
super();
}
}
The Object class has a bunch of native (non-Java) code within it to register with the JVM ensuring correct garbage collection, memory management, type enforcement, etc. are followed over the life of the Object.
ie. You can't get around it, the JVM will stop you from constructing and abstract class unless all of it's methods can be resolved via anonymous classes or subclasses.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With