aserción en 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;
}
}
compila básicamente 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 manera que Java sólo tiene que llamar Assert.class.desiredAssertionStatus()
vez en 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 nombres con otros campos que podemos definir. Por ejemplo, la siguiente falla al compilar 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;
}
}
La única cosa que "previene", es la convención de nomenclatura de no utilizar dólares en sus identificadores. Ver también: When should I use the dollar symbol ($) in a variable name?
Bono:
static final int $assertionsDisabled = 0;
quiere trabajar, porque a diferencia de Java, el código de bytes permite varios campos con el mismo nombre pero diferentes tipos: Variables having same name but different type
no puedo creer que no es natural! – Mehrdad