Допустим, у меня есть следующие настройки
и interface
public interface TestInterface {
public void draw();
}
и две реализации
public class Square implements TestInterface {
@Override
public void draw() {
System.out.println("Square");
}
}
и
public class Circle implements TestInterface {
@Override
public void draw() {
System.out.println("Circle");
}
}
Теперь я легко могу сделать
TestInterface a = new Square();
a.draw();
и я правильно получаю Square
. Затем я хотел попробовать отражение.
Class<?> clazz = null;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Constructor<?> constructor = null;
try {
constructor = clazz.getConstructor();
} catch (NoSuchMethodException | SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Object instance = null;
try {
instance = constructor.newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Method method = null;
try {
method = instance.getClass().getMethod(methodName);
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
method.invoke(instance);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
и для className
как some.package.Square
и methodName
как draw
я снова получаю Square
. Что правильно.
Проблема в том, что у моего приложения есть доступ к interface
, но нет реальных реализаций. Следовательно, я знаю, какие методы вызывать, но я также должен указать реализованные классы и не знаю, в каком пакете они могут находиться. Что если я знаю только имя класса, но не пакет?
Есть ли способ, где я все еще могу использовать форму инициализации
TestInterface a = new <some_parameter>();
a.draw();
Есть ли способ обобщить это? Или подход, использующий рефлексию, который я показал выше, является единственным способом достижения чего-то подобного? И, наконец, будет ли какая-то разница, если я использую абстрактный класс вместо интерфейса?