2011-04-06 16 views
14

Busqué la sintaxis y busqué en la API, pero todavía estoy confundido sobre el proceso. También busqué Stackoverflow. ¿Cuál es la forma correcta de cargar una clase y crear un objeto de forma dinámica? En otras palabras, quiero que el usuario especifique qué tipo de objeto quiere crear y luego crea ese tipo de objeto. No quiero un menú, porque quiero que puedan elegir cualquier clase dentro del directorio actual.cargando dinámicamente una clase en Java

+0

¿Está tratando de cargar una clase del archivo binary.class o por nombre de clase? –

+0

@JustinWaugh Hola Justin, ¿la respuesta aceptada es adecuada para cargar un archivo .class? – leaf

Respuesta

15

Suponiendo que la clase no tiene Arg-constructor, la forma más sencilla sería -

Object newObject = Class.forName(strFullyQualifiedClassName).newInstance(); 

Referencia - java.lang.Class

+0

¿Qué pasa si tiene arg, y cómo llamo a un método en la clase? ¿Cómo echo newObject solo por el nombre de la clase? Cuando intento llamar a un método de la clase en el tipo Objeto, me dice que el método no está definido para el objeto. – rubixibuc

+2

Si no conoce el tipo de clase en tiempo de compilación, deberá usar la función de reflexión para buscar y llamar a los métodos. Si el constructor tiene un argumento, usa 'getDeclaredConstructor()' en la clase devuelta desde 'Class.forName' como se muestra en la respuesta de Mike Samuel –

+0

+1 a Justin. Además, en términos prácticos, no puede ser que no sepas absolutamente nada sobre la clase, ya que será muy difícil usarla. Tener estas clases desconocidas implementando una interfaz particular suele ser una buena estrategia. a continuación, puede hacer referencia a estos objetos por las interfaces para que pueda llamar a métodos, etc. –

4

ClassLoader.loadClass cargará una clase. Obtiene un cargador de clases por myClass.getClassLoader() y debe recurrir a ClassLoader.getSystemClassLoader() si eso es nulo.

Una vez que tenga una instancia de clase, puede obtener sus constructores a través del getDeclaredConstructor(...). Así que si usted tiene un public class MyClass con un constructor como public MyClass(String) { ... } continuación

Class<MyClass> clazz = MyClass.class; 
Constructor<MyClass> ctor = clazz.getDeclaredConstructor(String.class); 
MyClass instance = ctor.newInstance("foo"); 

Lo anterior pasa por alto un montón de posibles excepciones.

+0

es MyClass una instancia o una referencia estática a la clase? ¿Hay alguna manera de obtener el contructor de una clase pasando su nombre como una cadena a un método? ¿O de alguna manera similar a eso? – rubixibuc

+0

'MyClass' es el nombre de la clase en este ejemplo. Una clase puede tener múltiples constructores (o ninguno para las interfaces); no hay "el constructor" para una clase. –

+0

El 'MyClass.class' puede ser una sintaxis confusa. Es solo una forma de referirse a la instancia de clase para 'MyClass'. Entonces 'String.class.isInstance (x)' es otra forma de decir 'x instanceof String'. –

4

Aquí es lo que tengo trabajo. Este no es un producto finalizado, sino que es solo una prueba para ver si puedo hacer que funcione. Gracias a todos los que respondieron la pregunta :-).

public class SimLoader { 
    public static void main(String[] args) 
    { 
    try 
    { 
    Object simulator = Class.forName("SimX").newInstance(); 
    ((SimInterface)simulator).run(); 
    } 
    catch(ClassNotFoundException e) {} 
    catch(InstantiationException e) {} 
    catch(IllegalAccessException e) {} 
    } 
    } 
interface SimInterface { 
void run(); 
} 
class SimX implements SimInterface 
{ 
    public void run() { 
    System.out.println("Success"); 
    } 
} 
+1

La mejor solución para mí. Pero no se olvide de usar FullyQualifiedName para Class (como com.mycomapy.SimX, en su ejemplo quizás no sea necesario). –

Cuestiones relacionadas