Reflexión de Java: crear una clase de implementación

Class someInterface = Class.fromName("some.package.SomeInterface"); 

¿Cómo creo ahora una nueva clase que implemente someInterface ?

Necesito crear una nueva clase y pasarla a una función que necesite SomeInterface como argumento.

Crear algo que pretende implementar una interfaz sobre la marcha en realidad no es demasiado difícil. Puede usar java.lang.reflect.Proxy después de implementar InvocationHandler para manejar cualquier llamada a métodos.

Por supuesto, podrías generar una clase real con una biblioteca como BCEL .

Si esto es para fines de prueba, debe buscar marcos de burla como jMock y EasyMock .

¡Fácilmente, java.lang.reflect.Proxy al rescate!

Ejemplo completo de trabajo :

 interface IRobot { String Name(); String Name(String title); void Talk(); void Talk(String stuff); void Talk(int stuff); void Talk(String stuff, int more_stuff); void Talk(int stuff, int more_stuff); void Talk(int stuff, String more_stuff); } public class ProxyTest { public static void main(String args[]) { IRobot robot = (IRobot) java.lang.reflect.Proxy.newProxyInstance( IRobot.class.getClassLoader(), new java.lang.Class[] { IRobot.class }, new java.lang.reflect.InvocationHandler() { @Override public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable { String method_name = method.getName(); Class< ?>[] classes = method.getParameterTypes(); if (method_name.equals("Name")) { if (args == null) { return "Mr IRobot"; } else { return args[0] + " IRobot"; } } else if (method_name.equals("Talk")) { switch (classes.length) { case 0: System.out.println("Hello"); break; case 1: if (classes[0] == int.class) { System.out.println("Hi. Int: " + args[0]); } else { System.out.println("Hi. String: " + args[0]); } break; case 2: if (classes[0] == String.class) { System.out.println("Hi. String: " + args[0] + ". Int: " + args[1]); } else { if (classes[1] == String.class) { System.out.println("Hi. int: " + args[0] + ". String: " + args[1]); } else { System.out.println("Hi. int: " + args[0] + ". Int: " + args[1]); } } break; } } return null; } }); System.out.println(robot.Name()); System.out.println(robot.Name("Dr")); robot.Talk(); robot.Talk("stuff"); robot.Talk(100); robot.Talk("stuff", 200); robot.Talk(300, 400); robot.Talk(500, "stuff"); } } 

Si desea ir más allá de las interfaces, es posible que desee echar un vistazo a cglib y objenesis . Juntos, te permitirán hacer cosas bastante poderosas, extender una clase abstracta e instanciarla. ( jMock los usa para ese propósito, por ejemplo).

Si quieres seguir con las interfaces, haz lo que dijo Jon Skeet :).

En realidad, debe usar el nombre de clase en el método Class.fromName () y convertirlo a su tipo de interfaz. Vea si la muestra a continuación ayuda.

 public class Main { public static void main(String[] args) throws Exception { Car ferrari = (Car) Class.forName("Mercedez").newInstance(); System.out.println(ferrari.getName()); } } interface Car { String getName(); } class Mercedez implements Car { @Override public String getName() { return "Mercedez"; } } class Ferrari implements Car { @Override public String getName() { return "Ferrari"; } }