¿Por qué es getClass () llama cuando se crea un objeto de la clase interna?

0ne0rZer0:

Estoy estudiando el funcionamiento de la clase interna y en el interior de su código de bytes, que estaba trazando la pila y no podía entender por qué se llama el getClass ()?
Me encontré con una pregunta similar para la función lambda , pero no podía entenderlo.

Yo trato de entender lo que se requiere para ninguna verificación nula, después de JDK 8 que ha sido reemplazado por una función estática llamada requiredNoNull.

código:

class Outer{
      class Inner{
      }
      public static void main(String args[]){
            Outer.Inner obj = new Outer().new Inner();
      } 
}

ByteCode:

 public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class Outer$Inner
       3: dup
       4: new           #3                  // class Outer
       7: dup
       8: invokespecial #4                  // Method "<init>":()V
      11: dup
      12: invokevirtual #5                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
      15: pop
      16: invokespecial #6                  // Method Outer$Inner."<init>":(LOuter;)V
      19: astore_1
regional predeterminada:

Por lo que yo entiendo, @ respuesta de Eugene es absolutamente correcto. He decidido añadir una explicación en palabras sencillas. Con suerte, será ayudar a alguien.

Respuesta: Las llamadas a Object.getClassfueron utilizados por el compilador en JDK8 para generar NullPointerExceptions cuando sea necesario. En su ejemplo, esta comprobación es innecesaria, ya que new Outer()no puede ser nulo, pero el compilador no era lo suficientemente inteligente como para determinarla.

En versiones posteriores de JDK, cheques nulos fueron cambiados para utilizar una más legible Objects.requireNotNull. El compilador también se ha mejorado para optimizar distancia cheques nulos redundantes.

Explicación:

Considere código como el siguiente:

class Outer{
      class Inner{
      }
      public static void main(String args[]){
            Outer.Inner obj = ((Outer) null).new Inner();
      } 
} 

Este código lanza una NullPointerException, como debe ser.

El problema es que la NPE es lógico desde el punto de vista de Java. Los constructores no existen en el nivel de código de bytes. El compilador genera un código de bytes más o menos equivalente a la siguiente pseudocódigo:

class Outer {
    public static void main(String[] args) {
         Outer tmp = (Outer) null;
         Outer.Inner obj = new; //object created
         tmp."<init>"(tmp);
    }
}
class Outer$Inner {
    //generated field
    private final Outer outer;
    //generated initializer
    void "<init>"(Outer outer) {
         this.outer = outer;
    }    
}

Como se puede ver, el constructor fue reemplazado con un método. Y el método, por sí mismo, no comprobarlo de argumento para nulo y, por lo tanto, no será una excepción.

Por esa razón, el compilador tiene que agregar un cheque nulo adicional para generar una NullPointerException. Antes de Java 8, la manera rápida y sucia para lograr esto era para emitir una llamada a getClass:

Outer tmp = (Outer) null;
tmp.getClass(); //generates an NPE

¿Cómo se puede comprobar que este es, de hecho, la razón:

  1. Compilar la Outerclase anteriormente usando JDK 8.
  2. Ejecutarlo, se debe lanzar una NPE.
  3. Retire la llamada a Object.getClasspartir Outer.classusando cualquier editor de código de bytes (por ejemplo JBE ).
  4. Ejecute el programa de nuevo, se debe completar con éxito.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=226131&siteId=1
Recomendado
Clasificación