Esta línea parece resumir el punto crucial de su problema:
El problema con esto es que ahora no se puede llamar a cualquier nuevos métodos (sólo overrides) en el implementar clase, ya que su variable de referencia de objeto tiene el tipo de interfaz.
Estás bastante atrapado en tu implementación actual, ya que no solo tienes que intentar un elenco, también necesitas la definición de los métodos que deseas invocar en esta subclase. Veo dos opciones:
1. Como se indica en otra parte, no puede usar la representación de cadena del nombre de clase para convertir su instancia reflejada a un tipo conocido. Puede, sin embargo, utilizar una prueba String
equals()
para determinar si su clase es del tipo que desea, y luego realizar un hard-coded reparto:
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();
}
Esto se ve muy feo, y arruina el buen config conducido por usted que tiene. No sugiero que hagas esto, es solo un ejemplo.
2. Otra opción que tienes es extender su reflexión desde sólo Class
/Object
creación de incluir Method
reflexión. Si puede crear el Class
desde un String pasado desde un archivo de configuración, también puede pasar un nombre de método desde ese archivo de configuración y, a través de la reflexión, obtener una instancia del propio Method
desde su objeto Class
. A continuación, puede llamar al invoke
(http://java.sun.com/javase/6/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object, java.lang.Object ...)) en el Method
, pasando la instancia de su clase que creó. Creo que esto te ayudará a obtener lo que buscas.
Aquí hay algunos códigos para que sirvan de ejemplo. Tenga en cuenta que me he tomado la libertad de codificar los parámetros para los métodos. Podrías especificarlos en una configuración también, y necesitaría reflejar en sus nombres de clase para definir sus obejcts e instancias 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();
}
}
}
y mi salida:
this is my instance:[email protected]
[email protected]:a message
[email protected]:another message:this is my message, from a config file, of course
¿Dónde puedo descargar el tarro de los métodos '' InterfaceType' y ImplementationType'? –