¿Cuándo se establece el indicador de modificador de acceso de bytecode JVM 0x1000 (hexadecimal)?

Para algún proyecto de analizador de código de bytes de Java, leí la especificación JVM y descubrí que los valores de máscara de bits de los campos del modificador de acceso al formato de archivo de clase de máquina virtual Java son

  ACC_PUBLIC = 0x0001
  ACC_FINAL = 0x0010
  ACC_SUPER = 0x0020 # old invokespecial instruction semantics (Java 1.0x?)
  ACC_INTERFACE = 0x0200
  ACC_ABSTRACT = 0x0400
  ACC_SYNTHETIC = 0x1000 
  ACC_ANNOTATION = 0x2000
  ACC_ENUM = 0x4000

De alguna manera no tengo idea de para qué 0x1000sirve. Lo vi una vez en una clase interna, pero para todas las clases internas que revisé desde entonces, esta bandera nunca se configuró. ¿Sabes cuál es el significado de esta bandera y dónde / cuándo se establece?

Respuesta 1

Un elemento sintético es cualquier elemento que está presente en un archivo de clase compilado pero no en el código fuente desde el que se compila. Al marcar un elemento para que sea sintético, permite una distinción de dichos elementos para las herramientas que procesan el código de forma reflexiva. Por supuesto, esto es, en primer lugar, relevante para las bibliotecas que usan la reflexión, pero también es relevante para otras herramientas como IDE que no le permiten llamar a métodos sintéticos o trabajar con clases sintéticas. Finalmente, también es importante que el compilador de Java verifique el código durante su compilación para nunca usar directamente elementos sintéticos. Los elementos sintéticos solo se utilizan para hacer feliz el tiempo de ejecución de Java, que simplemente procesa (y verifica) el código entregado donde trata los elementos sintéticos de forma idéntica a cualquier otro elemento.

Ya mencionó las clases internas como un ejemplo en el que el compilador de Java inserta elementos sintéticos, así que veamos una clase de este tipo:

class Foo {

  private String foo;

  class Bar {

    private Bar() { }

    String bar() {
      return foo;
    }
  }

  Bar bar() {
    return new Bar();
  }
}

Esto compila perfectamente bien pero sin elementos sintéticos, sería rechazado por una JVM que no sabe nada sobre las clases internas. El compilador de Java desugares la clase anterior a algo como lo siguiente:

class Foo {

  private String foo;

  String access$100() {  // synthetic method
    return foo;
  }

  Foo$Bar bar() {
    return new Foo$Bar(this, (Foo$1)null);
  }

  Foo() { } // NON-synthetic, but implicit!
}

class Foo$Bar {

  private final Foo $this; // synthetic field

  private Foo$Bar(Foo $this) {  // synthetic parameter
    this.$this = $this;
  }

  Foo$Bar(Foo $this, Foo$1 unused) {  // synthetic constructor
    this($this);
  }

  String bar() {
    return $this.access$100();
  }
}

class Foo$1 { /*empty, no constructor */ } // synthetic class

Como se dijo, la JVM no sabe acerca de las clases internas, pero impone el acceso privado de los miembros, es decir, una clase interna no podría acceder a las propiedades privadas de sus clases adjuntas. Por lo tanto, el compilador de Java necesita agregar los llamados accesores a una clase accedida para exponer sus propiedades no visibles:

  1. El foocampo es privado y, por lo tanto, solo se puede acceder desde dentro Foo. El access$100método expone este campo a su paquete en el que siempre se encuentra una clase interna. Este método es sintético, ya que lo agrega el compilador.

  2. El Barconstructor es privado y, por lo tanto, solo se puede llamar desde su propia clase. Para crear una instancia de una instancia Bar, otro constructor (sintético) necesita exponer la construcción de una instancia. Sin embargo, los constructores tienen un nombre fijo (internamente, todos se llaman <init>), por lo tanto, no podemos aplicar la técnica para los métodos de acceso donde simplemente los nombramos access$xxx. En cambio, hacemos que los accesos de constructor sean únicos al crear un tipo sintético Foo$1.

  3. Para acceder a su instancia externa, una clase interna necesita almacenar una referencia a esta instancia que se almacena en un campo sintético $this. Esta referencia debe ser entregada a la instancia interna por un parámetro sintético en el constructor.

Otros ejemplos de elementos sintéticos son clases que representan expresiones lambda, métodos de puente al anular métodos con firmas de tipo divergente, la creación de Proxyclases o clases creadas por otras herramientas como compilaciones de Maven o generadores de código de tiempo de ejecución como Byte Buddy (conector descarado )

Respuesta: 2

Tengo un formulario de inicio de sesión donde un usuario puede ingresar sus credenciales para iniciar sesión. Tengo un JLabel que sirve para mostrar el texto que le dice al usuario que el nombre de usuario no puede estar vacío. Esta etiqueta se muestra después de ...

He implementado una función de JavaScript dentro del servidor Mongodb usando este ejemplo. Funciona bien cuando uso mongo shell, pero quiero ejecutarlo desde un programa Java. Este es el código: público ...

Estoy usando interceptores cxf personalizados para registrar solicitudes / respuestas para llamadas de servicio y me gustaría registrar el tiempo que tardó la llamada junto con la respuesta. ¿Hay alguna forma de hacer esto?

Tengo un proyecto para que la escuela analice el código web y lo use como una base de datos. Cuando intenté bajar los datos de (https://www.marathonbet.com/en/betting/Football/), ¿no lo obtuve todo? Aquí está mi código: ...