Tcnicas avanzadas de programacin Introspeccin - PowerPoint PPT Presentation

1 / 9
About This Presentation
Title:

Tcnicas avanzadas de programacin Introspeccin

Description:

Podemos obtener la clase madre, los atributos, constructores y m todos de una clase. ... Para hallar la clase madre: Class clase = Class.forName( 'newInstance. ... – PowerPoint PPT presentation

Number of Views:49
Avg rating:3.0/5.0
Slides: 10
Provided by: r00021
Category:

less

Transcript and Presenter's Notes

Title: Tcnicas avanzadas de programacin Introspeccin


1
Técnicas avanzadas de programaciónIntrospección
  • Ramiro Lago

2
Introducción
  • Java tiene interesantes mecanismos para cargar
    clases de manera dinámica, conocer sus métodos y
    atributos, etc. Son formas de obtener información
    interna de las clases, incluso los objetos Java
    pueden informarnos de su propia estructura. Por
    ello se llaman utilidades de introspección.
  • La clase más importante es java.lang.Class. Es
    una clase que nos permite describir cualquier
    clase Java. Dicho de otra forma, es un descriptor
    o referencia de una clase.
  • Un paquete relevante es java.lang.reflect

3
Conocer el tipo
  • En tiempo de ejecución puede saber el tipo
    (clase) que manejamos
  • Si tenemos un objeto, puedo conocer su clase
  • Coche miCoche new Coche()
  • Class clase miCoche.getClass()
  • System.out.println("Clase" clase.getName() )
  • Lo que hemos hecho es obtener un descriptor de
    clase (tipo Class) mediante miCoche.getClass().
    Este descriptor nos devuelve su nombre mediante
    getName()
  • Si tenemos una clase (no hay instancias)
  • Coche.class.getName()
  • getName() nos devuelve el nombre de la clase,
    incluyendo la jerarquía de paquetes. En nuestro
    ejemplo
  • newInstance.dominio.Coche

4
Carga dinámica
  • Podemos cargar de manera dinámica un objeto, es
    decir, determinar en tiempo de ejecución (y no en
    tiempo de programación) la clase que vamos a
    instanciar
  • Primero haremos una pequeña clase (Coche) de
    prueba
  • package newInstance.dominio
  • public class Coche extends Vehiculo
  • private int plazas 5
  • public Coche()
  • public Coche( int plazas ) this.plazas
    plazas
  • public int getPlazas() return plazas
  • public void setPlazas( int p ) plazas p
  • public String toString()
  • try return super.toString() " Plazas"
    String.valueOf(plazas)
  • catch (Exception e) return "-1"
  • A continuación crearemos un objeto del tipo
    Class, que es un descriptor de la estructura de
    datos o clase. Lo conseguimos con forName(). El
    paso siguiente es crear una instancia de la clase
    con newInstance().
  • Class clase Class.forName( newInstance.dominio.
    Coche )
  • Object objeto clase.newInstance()
  • System.out.println(Coche" objeto.toString()
    )

5
Carga dinámica. Ejemplo (I)
  • Vamos a instanciar todas las clases de un
    directorio (paquete). strDirClases se obtiene
    previamente desde un archivo properties
  • .
  • //// Obtengo directorio de clases
  • File fDirClases new File( strDirClases )
  • if ( !fDirClases.isDirectory())
  • System.out.println("El directorio de clases no
    existe" )
  • return
  • //// Obtengo clases del directorio
  • File listaFicheros fDirClases.listFiles( new
    ClassFileFilter() ) // Ver siguiente
    transparencia
  • if (listaFicheros.length 0)
  • System.out.println("No hay clases en el
    directorio de clases" )
  • return
  • //// Instancio clases
  • System.out.println("\nClases instanciadas" )
  • String strClase ""
  • Object objeto null
  • for (int i 0 i lt listaFicheros.length i)

6
Carga dinámica. Ejemplo (II)
  • En este ejmplo se obtienen los archivos .class
    del directorio fDirClases (tipo File) por medio
    de la llamada
  • File listaFicheros fDirClases.listFiles( new
    ClassFileFilter() )
  • listFiles usa un filtro de ficheros para obtener
    sólo los .class. El filtro es una clase que
    implementa el interfaz java.io.FileFilter, lo que
    le obliga a implementar el método accept(). Este
    método devuelve true si el archivo (parámetro)
    pasa el filtro
  • public class ClassFileFilter implements
    java.io.FileFilter
  • public boolean accept(java.io.File f)
  • if (!f.isDirectory())
  • String name f.getName().toLowerCase()
  • return name.endsWith("class")
  • return false

7
Manejo de la estructura de la clase (I)
  • Podemos obtener la clase madre, los atributos,
    constructores y métodos de una clase. Para ello
    usaremos java.lang.reflect.
  • Para hallar la clase madre
  • Class clase Class.forName( "newInstance.dominio.
    Coche")
  • Class claseMadre clase.getSuperclass()
  • System.out.println( "Clase " clase.getName()
    ", hereda de " claseMadre.getName())
  • Para atributos, métodos y constructores es muy
    sencillo los atributos se representan por la
    clase Field, los constructores por Constructor y
    Method para los métodos. Partimos del descriptor
    de clase
  • Class clase Class.forName( "newInstance.dominio.
    Coche")
  • El descriptor de clase tiene los métodos
    getFields(), getConstructors() y getMethod(), que
    nos devuelven arrays de los objetos que buscamos.
    Pero sólo nos devuelve elementos públicos, hay
    una versión Declared de cada método get que nos
    devuelve cualquier elemento (privado, protegido o
    público), por ejemplo getDeclaredFields().
  • Field atrib clase.getDeclaredFields() //
    getFields() nos da solo los public
  • printLista( "Atributos", atrib )
  • //// Constructores y métodos
  • Constructor cons clase.getConstructors() //
    Sólo public
  • printLista( "Constructores", cons )
  • .
  • public static void printLista( String titulo,
    Object obj)
  • System.out.println( titulo )
  • for ( int i 0 i lt obj.length i)
  • System.out.println( " " obji.toString())

8
Manejo de la estructura de la clase (II)
  • Además podemos invocar un método. Primero debemos
    encontrarlo, para lo cual usamos el método
    getMethod(), especificando el nombre del método y
    los tipos de sus parámetros. En este caso
    buscamos el método setPlazas, que tiene un
    parámetro int
  • Class tiposParam int.class
  • Method metSetPlazas clase.getMethod(
    "setPlazas", tiposParam )
  • A continuación lo invocamos. También necesitamos
    un array, pero esta vez para los valores de los
    parámetros
  • Coche miCoche new Coche()
  • Object argumentos 7
  • metSetPlazas.invoke( miCoche, argumentos )
  • Invoke si el método es static el primer
    argumento (miCoche en nuestro ejemplo) puede ser
    null. El segundo puede ser null si no tiene
    parámetros, en concreto (Object) null.
  • Para comprobar el resultado puede usar
    miCoche.toString()

9
Midiendo el tiempo
  • Hay una forma sencilla de medir el tiempo de
    invocación de un método, con System.currentTimeMil
    lis()
  • //// Busca método toString (de otra forma,
    recorriendo array de Method) y lo invoca
  • //// Ojo búsqueda imperfecta, en caso de
    sobrecarga de métodos, toma el primero
  • //// Además con System.currentTimeMillis()
    medimos tiempo de llamada
  • for ( int i 0 i lt mets.length i)
  • if ( metsi.getName().equals( "toString") )
  • System.out.println( "Encontrado método "
    metsi.getName())
  • long inicio System.currentTimeMillis()
  • String cadena (String) metsi.invoke(
    miCoche, (Object) null)
  • long fin System.currentTimeMillis()
  • System.out.println( "Invocado método "
    cadena)
  • System.out.println( "Tiempo empleado por
    invoke() " (fin - inicio))
Write a Comment
User Comments (0)
About PowerShow.com