Эта строка, кажется, подводит итог вашей проблемы:
Проблема в том, что теперь вы не можете вызывать какие-либо новые методы (только переопределения) для реализующего класса, так какПеременная ссылки на объект имеет тип интерфейса.
Вы довольно застряли в своей текущей реализации, поскольку вам нужно не только выполнить приведение, но и определить метод (ы), который выхочу позвонить на этот подкласс.Я вижу два варианта:
1. Как указано в другом месте, вы не можете использовать строковое представление имени класса для приведения вашего отраженного экземпляра к известному типу.Однако вы можете использовать тест String
equals()
, чтобы определить, соответствует ли ваш класс тому типу, который вам нужен, и затем выполнить жестко закодированное приведение:
try {
String className = "com.path.to.ImplementationType";// really passed in from config
Class c = Class.forName(className);
InterfaceType interfaceType = (InterfaceType)c.newInstance();
if (className.equals("com.path.to.ImplementationType") {
((ImplementationType)interfaceType).doSomethingOnlyICanDo();
}
} catch (Exception e) {
e.printStackTrace();
}
Это выглядит довольно уродливо,и это разрушает хороший процесс, управляемый конфигурацией, который у вас есть.Я не предлагаю вам сделать это, это просто пример.
2. Другой вариант, который у вас есть, - расширить свое отражение от всего лишь Class
/ Object
создания, включив в него Method
отражение.Если вы можете создать Class
из строки, переданной из файла конфигурации, вы также можете передать имя метода из этого файла конфигурации и, с помощью отражения, получить экземпляр самого Method
из вашего объекта Class
,Затем вы можете вызвать invoke
(http://java.sun.com/javase/6/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object, java.lang.Object ...)) на Method
, передав экземпляр вашего класса, который вы создали.Я думаю, что это поможет вам получить то, что вы ищете.
Вот код, который можно использовать в качестве примера.Обратите внимание, что я взял на себя смелость кодировать параметры для методов.Вы также можете указать их в конфиге, и вам нужно будет подумать об именах их классов, чтобы определить их Class
объекты и экземпляры.
public class Foo {
public void printAMessage() {
System.out.println(toString()+":a message");
}
public void printAnotherMessage(String theString) {
System.out.println(toString()+":another message:" + theString);
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("Foo");
Method method1 = c.getDeclaredMethod("printAMessage", new Class[]{});
Method method2 = c.getDeclaredMethod("printAnotherMessage", new Class[]{String.class});
Object o = c.newInstance();
System.out.println("this is my instance:" + o.toString());
method1.invoke(o);
method2.invoke(o, "this is my message, from a config file, of course");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException nsme){
nsme.printStackTrace();
} catch (IllegalAccessException iae) {
iae.printStackTrace();
} catch (InstantiationException ie) {
ie.printStackTrace();
} catch (InvocationTargetException ite) {
ite.printStackTrace();
}
}
}
и мой вывод:
this is my instance:Foo@e0cf70
Foo@e0cf70:a message
Foo@e0cf70:another message:this is my message, from a config file, of course