If you have an abstract class you can instantiate it by deriving an concrete anonymous class. This is an example:
abstract class A {
abstract void hello ();
}
A say = new A () { void hello () { System.out.println ("hello"); } }
say.hello(); // -> hello
How to do the same if the class is stored in a Class object? Here is an example:
// -*- compile-command: "javac anon.java && java anon"; -*-
class anon
{
anon () throws Exception {}
abstract class AbstractClass
{
AbstractClass () throws Exception {}
abstract void id ();
}
AbstractClass x = new AbstractClass ()
{
void id () { System.out.println ("X"); }
};
Class<AbstractClass> abstractclass
= (Class<AbstractClass>)Class.forName ("anon$AbstractClass");
AbstractClass y = abstractclass.getConstructor().newInstance();
public static void main (String argv[]) throws Exception
{
anon main = new anon();
main.x.id(); // should print "X"
main.y.id(); // should print "Y"
}
}
The first instantiation (x) works fine but the second (y) fails because it tries to instantiate the abstract class directly without deriving a concrete class. How can I do this in Java having only a Class object?
Abstract classes cannot be instantiated, but they can be subclassed. When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract .
Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name.
We cannot instantiate an abstract class in Java because it is abstract, it is not complete, hence it cannot be used.
You may have a misunderstanding on how exactly anonymous classes work. An anonymous class is in fact a regular class just like any other and has its own class file. Java-the-language only provides some syntactic sugar over this and allows a less verbose syntax for something that you can exactly mimic by declaring a regular named top-level class in its own file. This is why you will find the Reflection API useless for what you want to achieve. Basically, you want to dynamically create a class that doesn't have its class file. For this you need a suitable library, such as javassist
.
If A
would be an interface instead of an abstract class, you can do this with a dynamic proxy, but that doesn't work with an abstract class. Example of how this works with an interface:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface A {
void hello();
}
public class Example {
public static void main(String[] args) throws Exception {
@SuppressWarnings("unchecked")
Class<A> cls = (Class<A>) Class.forName("A");
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(method.getName());
return null;
}
};
A instance = (A) Proxy.newProxyInstance(cls.getClassLoader(),
new Class<?>[] { cls }, handler);
instance.hello();
}
}
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