2008-11-26 18 views
6

¿Hay alguna otra manera que no sea usar el reflejo para acceder a los miembros de una clase interna anónima?Acceso a los miembros internos de la clase anónima

+0

puedo preguntar ¿Por qué querrías hacer eso? Algún contexto. No estoy seguro de si es una buena idea, incluso si es posible. – Gishu

+0

No tengo ningún caso de uso específico. Solo quería saber si hay algún otro mecanismo que no sea la reflexión para consultar/acceder a los miembros del objeto –

Respuesta

9

Las clases internas anónimas tienen un tipo pero no un nombre.

Puede acceder a los campos no definidos por el supertipo indicado. Sin embargo, una vez asignado a una variable de tipo nombrado, la interfaz se pierde.

Obviamente, puede acceder a los campos desde dentro de la clase interna. Una forma de añadir código es a través de una instancia initialiser:

final AtomicInteger y = new AtomicInteger(); 
new Runnable() { 
    int x; 
    { 
     x = 5; 
     doRun(this); 
     y.set(x); 
    } 
    public void run() { 
     ... blah ... 
    } 
}; 

El valor devuelto por la expresión de la clase interna anónima tiene el tipo anónimo, por lo que tiene una oportunidad de usarlo fuera de la clase en sí:

final int y = new Runnable() { 
    int x; 
    { 
     x = 5; 
     doRun(this); 
    } 
    public void run() { 
     ... blah ... 
    } 
}.x; 

también se puede pasar a través de un método similar al declarado:

<T extends Runnable> T doRun(T runnable); 
0

Si implementa una interfaz o amplía una clase existente, puede acceder a los miembros definidos en la interfaz o clase base.

0

Mr Fooz tiene razón, excepto que las interfaces solo pueden definir miembros constantes. la mejor manera sería agregar métodos getter/setter a su interfaz y luego usarlos para obtener su valor. pero luego para cada clase anónima tendrías que definir esos métodos (tipo de dolor).

+0

El método son miembros de sus tipos igual que los campos. – erickson

9

Puede usar clases locales en lugar de anónimas. Mira:

public class Test { 
    public static void main(String... args) { 
     class MyInner { 
      private int value = 10; 
     } 

     MyInner inner = new MyInner(); 
     System.out.println(inner.value); 
    } 
} 

Usted puede tener referencia de MyInner tipo sólo en el cuerpo del método sin embargo. Por lo tanto, fuera del método, no podrá usar sus campos/métodos que no están declarados en su súper clase (java.lang.Object en este caso) o en la interfaz.

+0

Guau ... nunca antes los había visto. Extraño. No puedo decir que me guste mucho, pero de todos modos es interesante :) –

+0

Se llaman clases locales. –

+0

Si no me equivoco, la clase que ha mostrado es solo otra clase con visibilidad limitada ... ¿no? Quise decir la pregunta para saber el posible acceso a los miembros de un objeto de clase anónimo. –

1

public class AccessAnonymous { 
    private Runnable runnable; // to have instance of the class 

    public static void main(String[] args) throws Exception { 
     AccessAnonymous a = new AccessAnonymous(); 
     a.a(); // init field 

     Class clazz = a.runnable.getClass(); 
     Field field = clazz.getDeclaredField("i"); 
     field.setAccessible(true); 

     int int1 = field.getInt(a.runnable); 
     System.out.println("int1=" + int1); 
    } 

    public void a() { 
     runnable = new Runnable() { 
      private int i = 1; 

      public void run() { 
       i = 90; 
      } 

     }; 
     runnable.run();// change value 
    } 
} 
0

Si desea código legible, fácil de mantener, no utilizan las clases anónimas. Si usa clases anónimas y desea un código legible y mantenible, no use clases anónimas cuando necesite acceder al elemento en esa clase interna. Hay formas de hacerlo, pero te ruego que no uses ninguno de esos hacks. La legibilidad supera todas las demás virtudes.

1

En el caso de las clases anónimas, también hay una compensación entre el desorden causado por la clase y la conveniencia de tenerlo anónimo. Las clases complicadas raramente pertenecen como anónimas, sino más bien como llamadas internas privadas.

En la mayoría de las clases anónimas, solo necesitamos "alimentar" el conocimiento y podemos hacerlo en la construcción. En algunas clases anónimas (por ejemplo, vehículos con valor de retorno) también nos preocupamos por un valor de retorno.

Como sabemos, no se debe acceder directamente a los miembros de datos, sino con un setter getter. Esto, si te encuentras en una situación en la que has agregado muchos getters y setters, probablemente estés haciendo algo mal de todos modos y no deberías estar usando una clase anónima.

Cuestiones relacionadas