java - tipos - JDK 1.7 vs JDK 1.6 diferencia de herencia de clases internas
funciones anonimas java 8 (2)
Estoy en la solución de algunos rompecabezas de Java y me encontré con este:
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {}
}
Al compilar este código con javac 1.6.0_45
, javac 1.6.0_45
, como se esperaba, este error:
Outer.java:8: cannot reference this before supertype constructor has been called
class Inner2 extends Inner1 {}
^
Esto se debe a que el compilador genera el constructor predeterminado para la clase Inner2
con código similar, lo que explica el error anterior:
Inner2 () {
this.super();
}
Y es obvio ahora, porque realmente no puedes hacer esto en Java 1.6.0_45, JLS 8.8.7.1 (como puedo adivinar):
Una declaración de invocación de constructor explícita en un cuerpo de constructor no puede referirse a ninguna variable de instancia o método de instancia declarado en esta clase o cualquier superclase, o usar esta o super en cualquier expresión; de lo contrario, se produce un error en tiempo de compilación.
Consulte ( respuesta aceptada en situación impar para "no se puede hacer referencia a esto antes de que se haya llamado al supertipo constructor" )
Pero si intento compilarlo con javac 1.7.0_79
, ¡está bien!
Y aquí va la pregunta: ¿Qué se ha cambiado en Java 1.7, que este código ahora es correcto?
¡Gracias por adelantado!
Parece que hubo una discusión sobre el mismo problema que el error JDK-6708938: la llamada de un súper constructor sintético nunca debe usar ''esto'' como calificador en el rastreador de errores de Java.
También creo que sería genial para usted ver otras cuestiones relacionadas de la anterior, por ejemplo JDK-4903103: No se pueden compilar subclases de clases internas .
Observe las versiones fijas de ambos errores.
Y como resultado, consulte la Revisión de mantenimiento de JSR 901 (Especificación del lenguaje Java) para Java SE 7 .
De la especificación del lenguaje Java Tercera edición
De lo contrario,
S
es una clase miembro interna (§8.5). Es un error en tiempo de compilación siS
no es miembro de una clase que contiene léxicamente, o de una superclase o superinterfaz de la misma. SeaO
la clase envolvente léxica más interna de la queS
es un miembro, y sea n un número entero tal queO
es la n clase que encierra léxicamente. La instancia que encierra inmediatamente dei
con respecto aS
es la instancia que encierra léxicamente n de esto.
Y de la Revisión de mantenimiento de JSR 901 (Especificación del lenguaje Java) para Java SE 7 (versión completa, página 242, texto azul) o lo mismo en la Especificación del lenguaje Java, edición de Java SE 7 (justo antes de la sección 8.8.8)
De lo contrario, S es una clase miembro interna (§8.5).
Sea O la clase de S que encierra léxicamente más interna, y sea n un número entero tal que O es la novena clase de C que encierra léxicamente.
La instancia inmediatamente adjunta de i con respecto a S es la novena instancia adjunta léxicamente de esto.
Así que puedes ver que la parte con error de compilación se ha ido.
Sospecho que tiene que ver con la dinámica de invocación que se agregó en java 1.7 para preparar la lambda en java 8.