Keep in touch

RSS Feed Twitter Facebook Delicious

Subscribe via Email

Reflexión en Java I, Instancia una clase desconocidas en tiempo de ejecucióni

April 27th, 2010 by pako received 9 Comments »

La Reflexión es el mecanismo mediante el cual java puede conocer clases ya compiladas y nos permite conocer cualquier clase con tan solo conocer su nombre así como crear instancia de los objetos e interactuar con los métodos de la misma, este puede tener diversas aplicaciones, en un siguiente post les mostrare como aprovecho esta ventaja en la programación en Web de Java por ahora me limito a mostrar algo de la API, en este post solo mostrare como crear la instancia de un objeto en post posteriores mostrare como obtener información de la clase y interactuar con sus métodos.
Para poder instanciar una clase con solo conocer su nombre y o ubicación en el classpath, ojo la clase tiene que estar en el claspath algo lógico por que si no lo esta java no la encontrará.

Para Ejemplificar creare dos clase A y B:

Class A

public class A {
    @Override
    public String toString() {
        return "Esto es una clase A";
    }
}

Class B

public class B {
    @Override
    public String toString() {
        return "esto es una B";
    }

}

Como observara solo he definido el método toString() que sobrescribe el método heredado desde java.lang.Object, este método se invoca al tratar de convertir un objeto a String por ejemplo al querer imprimirlo con un System.out.println()
Para Obtener la clase desde un string haremos uso del método estático forName() de la clase Class, esta clase nos provee distintos métodos para obtener información de una clase, si han manejado drivers jdbc recordaran haber utilizado este método.
Ejemplo :

Class _class = Class.forName(“A”);

Con esto se almacena la clase (el molde, no la instancia) de la clase A, observe que se envía una cadena esto hace que esto pueda ser dinámico en tiempo de ejecución ya que podemos tener una variable y esta enviarla al Class.forName, si la clase no se encuentra se genera una excepción tipo ClassNotFoundException .
Una ves que tenemos la clase podremos llamar a su constructor por defecto (el que no recibe ningún parámetro, constructores con parámetros los mostrare en otro post)

Para crear la instancia haremos uso del método .newInstance(); del objeto Class que almacene nuestra clase en nuestro ejemplo _class, este métodos pueden generar excepciones tipo InstantiationException, IllegalAccessException

Object obj=_class.newInstance();

Las excepciones las podemos manejar con campos try/catch o bien agregando throws al inicio de nuestro método.
Para ver que realmente estamos instanciando un objeto del tipo marcado en Class.forName, mandare imprimir el objeto.

System.out.println(obj);

Con esto mando implícitamente el método .toString(), podrán observar la salida en la consola y debería de mostrar el mensaje:

“Esto es una clase A”

Aquí el código de la clase que usa la reflexión
reflexion1.java

public class refexion1 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class _class = Class.forName("A");
        Object obj = _class.newInstance();
        System.out.println(obj);

    }
}

Ahora cambie el parámetro de Class.forName a “B”, y pruebe observara que el mensaje ha cambiando por

“esto es una B”

Por último modifico la clase para que atreves del teclado el usuario me indique que clase instanciar.

import java.util.Scanner;
public class refexion1 {
    public static void main(String[] args) {
        System.out.println("Escribe A o B");
        String strClase = new Scanner(System.in).nextLine();
        try {
            Class _class = Class.forName(strClase.toUpperCase());
            Object obj;
            try {
                obj = _class.newInstance();
                System.out.println(obj);
            } catch (InstantiationException ex) {
                System.out.println("Error al Instaciar laClase");
            } catch (IllegalAccessException ex) {
                System.out.println("Error al Instaciar laClase");
            }
        } catch (ClassNotFoundException ex) {
            System.out.println("La Clase No existe");
        }
    }
}

Espero este post allá despertado su interés.. próximamente les digo como obtener información, instanciar con constructores con parámetros, obtener información de los métodos y sus parámetros y como interactuar con ellos.

Código fuente en proyecto de netBeans 6.8 http://www.megaupload.com/?d=NU41A5D0

>> Reflexión en Java II, Obtener propiedades de una clase desconocidas en tiempo de ejecución

>> Reflexión en Java III, Acceso y modificación de propiedades

Tags: , ,

Posted under: Java


9 Responses to “Reflexión en Java I, Instancia una clase desconocidas en tiempo de ejecucióni”

  1. [...] En el pos anterior mostré como instanciar un par de clases sencillas según una cadena obtenida desde el teclado esto sin saber que teclearía el usuario y sin usar if’s ni switch si no con la reflexión que es el mecanismo por el cual podemos conocer los detalles y manejar en tiempo de ejecución de una clase “desconocida” en codificación. En este post mostrare como obtener información de las propiedades de nuestra clase. Para este post he modificado las clases A y B, agregándole propiedades classA [...]

  2. [...] << Reflexión en Java I, Instancia una clase desconocidas en tiempo de ejecución << Reflexión en Java II, Obtener propiedades de una clase desconocidas en tiempo de ejecució… [...]

  3. marco says:

    hey porfa necesito ayuda para ingresar en char variables por el Scanner si es q se puede o si me pueden ayudar cm se hace

  4. marco says:

    es en java 6.8 gracias
    de antemano

  5. Carlos La Serna says:

    Quisiera saber como se hace para acceder a métodos de otra clase que se encuentra declarada dentro de nuestro Clase Instanciada.

    Ejemplo:

    class Usuario {
    private String nombre;
    private String email;

    los getter y setter
    }

    La clase a continuación es sobre la que vamos a hacer reflection:

    class Ejecutar {
    private String hora;

    private String proceso;

    private Usuario user;

    // Getter y Setter

    como puedo acceder a los métodos de Usuario, desde Reflection.

    }

    Mil Gracias.

  6. PakoS says:

    @Carlos La Serna listo ya tengo un ejemplo en mi post 4 de reflexión recién redactado =), en un rato hago el post para ejecutar métodos con parametros

  7. LP says:

    Amigo si sin duda lo q hasta publicado es correcto, pero este ejemplo solo llama a una clase dentro de un determinado paquete, si quisieras llamar a una clase que esta en otro paquete no se instanciaria… como seria en ese caso ????

  8. LP says:

    para aquellos q recien se inician en esto seria lo siguiente:

    Class _class = Class.forName(“NombreDelPaquete.NombredeClase”);

    como vees es posible llamar a cualquier clase instanciandolo solo se agrega el punto “.” ,,, un saludo.

  9. pako says:

    @LP asi es!, si tu clase se encuetra en otro package tienes dos posibilidades importar el package directamente al inicio de tu programa, que hablando de reflexion esto no seria muy logico, o bien como lo mencionas basta con que la cadena de donde obtendra tu clase tenga la ruta correcta a tu Clase

    Class objClass = Class.forName(“otroPackage.UnaClase”);


Leave a Reply


*