Execute Java classes that implement a specific interface using reflection
I am new to Reflection. I've seen some questions and tutorials.
Suppose I have one interface which is implemented by 3 classes A, B, C
public interface MyInterface {
doJob();
}
Now using reflection I want to call each class
Class<?> processor = Class.forName("com.foo.A");
Object myclass = processor.newInstance();
Instead of creating an object, I cannot constrain the whole process to a specific type. I only want to use the MyInterface classes .
If I pass com.foo.A it should create an object of class A, com.foo.B should execute an object of class B, but if I pass some com.foo.D that exists but still doesn't implement MyInterface t is called ...
How can I achieve this?
source to share
try
MyInterface newInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> cls = Class.forName(className);
if (!MyInterface.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException();
}
return (MyInterface) cls.newInstance();
}
source to share
Well, Java Reflection is a general purpose mechanism, so if you only use the code you presented in the question, it is impossible to achieve what you want to achieve. This is exactly the same as asking how to restrict Java to create objects of types other than those that implement "MyInterface". Java 'new' is a general purpose and it will allow you to create any object you want.
In general, you can write your own code for this. And instead of a direct call
Class.forName
Call your own code
You can implement something like this at compile time / run time.
An example of compilation type checking (you need the generated class object):
public T newInstance(Class<T extends MyInterface cl) {
return cl.newInstance();
}
The runtime example was posted by Evgeny Dorofeev already
Hope it helps
source to share
try under code
package com.rais.test;
public class Client {
public static void main(String[] args) {
try {
System.out.println(createObject("com.rais.test.A"));
System.out.println(createObject("com.rais.test.D"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static MyInterface createObject(String className)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
Class<?> clazz = Class.forName(className);
if (MyInterface.class.isAssignableFrom(clazz)) {
return (MyInterface) clazz.newInstance();
} else {
throw new RuntimeException(
"Invalid class: class should be child of MyInterface");
}
}
source to share