What is Java Synthetic Field (ACC_SYNTHETIC)? with the example of AbstractExecutorService.$assertionsDisabled in java package java.util.concurrent

A Java field in .class file marked with the ACC_SYNTHETIC flag to indicate that it was generated by a compiler and does not appear in source code.

Binary Code is always the best document, so let's inspect an example of this case, from the class AbstractExecutorService (source code) in the package java.util.concurrent.

The UML generated form the AbstractExecutorService.class file indicates it contains a field named $assertionsDisabled, and the detailed inspection shows this field is generated by compiler, since its "Access Flags" contains the value synthetic, which means this field "not present in the source code".

UML diagram generated from AbstractExecutorService.class

Details page for the field AbstractExecutorService.$assertionsDisabled


So why Java compiler is generating this field? Let's continue to inspect the field AbstractExecutorService.$assertionsDisabled.

From the .class binary data analysis, the field AbstractExecutorService.$assertionsDisabled is used by the following two methods:
  1. Method AbstractExecutorService.invokeAny(), at byte code offset position 9  
  2. Method AbstractExecutorService.[class-constructor](), at byte code offset position 13


Used by Method analysis on the field AbstractExecutorService.$assertionsDisabled

Let's open the source code of the method AbstractExecutorService.invokeAny(), we can find that in the line 222, we have an assert stathemt here.


217    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
218        throws InterruptedException, ExecutionException {
219        try {
220            return doInvokeAny(tasks, false, 0);
221        } catch (TimeoutException cannotHappen) {
222            assert false;
223            return null;
224        }
225    }

Based on JSR 41: A Simple Assertion Facility, the compiler may generate a static field named $assertionsDisabled and/or $assertionsEnabled, to help processing the Java assert keyword easier.

The value of the $assertionsDisabled and/or $assertionsEnabled field could be set via the method Class.desiredAssertionStatus(), and the binary code decode result of the class constructor method of AbstractExecutorService confirmed JSR 41:

  • The generated class constractor method of AbstractExecutorService, is trying to get the assert value from Class.desiredAssertionStatus(), then set the field $assertionsDisabled accordingly.

Decoded bytecode of the class constructor of AbstractExecutorService


Comments

Popular posts from this blog

What is Java Bridge Method (ACC_BRIDGE)?

What is Java Synthetic Class (ACC_SYNTHETIC)? with the example of BoundMethodHandle$1.class in Java package java.lang.invoke

Evolution of Java Dependency Diagrams, from Java 7 to Java 13