En Java, cada vez que se crea una instancia de clase interna, se asocia con una instancia de una clase externa. Por curiosidad, ¿es posible asociar la clase interna con otra instancia de una clase exterior en su lugar?¿Es posible cambiar la instancia de clase externa de una clase interna en Java?
Respuesta
Sí, esto es posible, a pesar de que suena como una muy mala idea. La idea es establecer el puntero de lo contrario final
a la instancia externa utilizando reflexión (que no se garantiza que tenga éxito).
import java.lang.reflect.*;
public class Me {
final String name;
Me(String name) {
this.name = name;
}
class InnerMe {
String whoAreYou() {
return name;
}
}
InnerMe innerSelf() {
return new InnerMe();
}
public static void main(String args[]) throws Exception {
final Me me = new Me("Just the old me!");
final InnerMe innerMe = me.innerSelf();
System.out.println(innerMe.whoAreYou()); // "Just the old me!"
Field outerThis = innerMe.getClass().getDeclaredFields()[0];
outerThis.setAccessible(true);
outerThis.set(innerMe, new Me("New and improved me!"));
System.out.println(innerMe.whoAreYou()); // "New and improved me!"
}
}
La parte crucial aquí es outerThis.setAccessible(true);
- un SecurityManager podría imponer una política que prohíbe este tenga éxito.
Debería poder hacerlo, mediante el reflejo.
Acaba de obtener todos los campos de la clase interna (getClass().getDeclaredFields()
) y ver qué campo tiene el padre, y luego cambiarlo (usando field.set(innerInstance, newParent)
Antes de que usted debe hacer que el campo accesible -. setAccessible(true)
)
Puesto que el campo parece ser final
, puede echar un vistazo a this article para ver cómo eludir eso.
Dicho esto, no debería necesitar hacer esto en absoluto; sería un truco feo doble sin ganancia real.
Si usted está hablando sobre el tiempo de instancias, es posible utilizar la siguiente sintaxis:
public class Outer {
public class Inner {}
}
...
Outer o = new Outer();
Outer.Inner i = o.new Inner();
Sin embargo, no es posible (sin setAccessible(true)
) para asociar la instancia existente de clase interna con la otra instancia de la clase externa , porque el campo que apunta a la instancia que encierra es final
:
javap Outer$Inner
Compiled from "Outer.java"
public class Outer$Inner extends java.lang.Object{
final Outer this$0;
public Outer$Inner(Outer);
}
(+1) buen lugar con el 'final'. – Bozho
+1 for 'o.new Inner()' - Hoy aprendí una nueva sintaxis. –
- 1. acceso clase externa "super" de clase interna en Java
- 2. ¿Cómo hacer referencia a la clase externa en otra instancia de una clase interna no estática?
- 3. Creando una instancia de la clase interna
- 4. clase interna y externa de clase en C#
- 5. Java: llamando al método de la clase externa en la clase interna anónima
- 6. Clase interna que accede a la clase externa
- 7. La subclasificación clase interna de la clase externa versus otra clase interna
- 8. En Java, ¿cómo accedo a la clase externa cuando no estoy en la clase interna?
- 9. cómo acceder a una variable de clase de la clase externa de clase interna en rubí
- 10. Referencia de clase para una clase interna Java
- 11. ¿Cómo se puede acceder a "esto" de la clase externa desde una clase interna?
- 12. Una clase interna retorcida en Java
- 13. ¿Cómo se obtiene una referencia a la clase adjunta de una clase interna anónima en Java?
- 14. volver más de una instancia de una clase interna anónima
- 15. Clase estática interna en Java
- 16. ¿Es posible tener una instancia de clase de tipo "local"?
- 17. de palabra clave para la clase externa de una clase interna anónima
- 18. ¿Cómo acceder a la variable de clase externa sombreada desde la clase interna?
- 19. ¿Propósito de una clase interna?
- 20. Llamar a la función de clase externa desde la clase interna
- 21. acceso a los datos privados de los miembros de la clase externa en la clase interna
- 22. Cómo crear una instancia de PrivateType de clase privada interna
- 23. ¿Puede una clase externa acceder a los miembros de la clase interna?
- 24. Devuelve el puntero a la clase interna anidada de la clase externa genérica
- 25. Java: Clase de devolución (No es una instancia)
- 26. ¿Es posible cambiar la clase de un objeto Ruby?
- 27. ¿Cómo hacer que una clase externa sea heredada de una clase interna?
- 28. Java clase interna rompecabezas visibilidad
- 29. Java: estático vs clase interna
- 30. ¿Es posible cambiar la hora actual de una instancia de hilo o jvm en java?
Aparte de su potencial en futuros concursos de java ofuscados, ¿cuál es el punto? Sabes que si quieres una clase interna que pueda desasociarse de su padre, puedes declararla estática, ¿verdad? –
Encuentro este problema fascinante. ¿Alguien sabe dónde en el JLS se especifica cómo se nombra el puntero a la clase externa? A través de la experimentación, me parece que parece ser 'este $ 0', a la que se añaden tantos '$' como sea necesario (posiblemente ninguno). ¿Esto está realmente especificado? – polygenelubricants
OK Acabo de descubrir que una clase interna de segundo nivel usa 'this $ 1' en su lugar. ¡Fascinante! – polygenelubricants