java bytecode disassembly java-synthetic-methods

java - ¿Cuál es el significado de "sintético estático"?



bytecode disassembly (3)

Assert on Oracle JDK 1.8.0_45 es un ejemplo que genera un campo static synthetic :

public class Assert { public static void main(String[] args) { assert System.currentTimeMillis() == 0L; } }

básicamente compila a:

public class Assert { // This method is synthetic. static final boolean $assertionsDisabled = !Assert.class.desiredAssertionStatus(); public static void main(String[] args) { if (!$assertionsDisabled) { if (System.currentTimeMillis() != 0L) { throw new AssertionError(); } } } }

Esto se puede verificar con:

javac Assert.java javap -c -constants -private -verbose Assert.class

que contiene:

static final boolean $assertionsDisabled; descriptor: Z flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC

El campo sintético se genera de modo que Java solo necesita llamar a Assert.class.desiredAssertionStatus() una vez en el tiempo de carga, y luego almacena el resultado allí.

Vea también: https://stackoverflow.com/a/29439538/895245 para una explicación más detallada.

Tenga en cuenta que este campo sintético puede generar conflictos de nombre con otros campos que podemos definir. Por ejemplo, lo siguiente no se compila en Oracle JDK 1.8.0_45:

public class Assert { static final boolean $assertionsDisabled = false; public static void main(String[] args) { assert System.currentTimeMillis() == 0L; } }

Lo único que "impide" es la convención de nomenclatura de no usar dólares en sus identificadores. Ver también: ¿ Cuándo debo usar el símbolo de dólar ($) en un nombre de variable?

Prima:

static final int $assertionsDisabled = 0;

Funcionaría, porque a diferencia de Java, el bytecode permite múltiples campos con el mismo nombre pero diferentes tipos: Variables que tienen el mismo nombre pero diferente tipo

Estoy viendo un código desensamblado obtenido a partir del código de bytes de Java. Veo alguna declaración de la siguiente manera:

.method static synthetic access$0()Lcom/package/Sample;

No puedo averiguar qué significa el synthetic o el access$0 . ¿Puede alguien ayudarme por favor a entender esta parte?


En el lenguaje java, las clases internas pueden acceder a los miembros privados de su clase adjunta. Sin embargo, en Java bytecode, el concepto de clases internas no existe, y los miembros privados no son accesibles. Para evitar esto, el compilador crea métodos de acceso sintéticos en la clase externa. Creo que eso es lo que están viendo aquí. access$0 es simplemente el nombre del método. No estoy seguro de qué, si algo hace el synthetic . Simplemente puede ocultar el método de otros compiladores para asegurar la encapsulación.