A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://binarydoc.blogspot.com/2019/10/what-is-java-synthetic-class.html below:

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

When a

.class

file marked with the

ACC_SYNTHETIC

flag, it indicates the

.class

file was generated by

compiler

and does not appear in the corresponding

.java source code

.

Binary Code is always the best document, so let's check an example: the BoundMethodHandle$1.class class in java.base.jmod in JDK.

The class file BoundMethodHandle$1.class has been marked as synthetic flag, as shown bellow:

Basic Information of BoundMethodHandle$1.class 

UML diagram of BoundMethodHandle$1.class

And this class is used by the container class

BoundMethodHandle

:

Dependency Network diagram of BoundMethodHandle$1.class

This class does not exist in the original source code

BoundMethodHandle.java

, but generated by the java compiler, from the following

two (2)

methods in the Java class

BoundMethodHandle

:

  1. BoundMethodHandle.bindSingle(), at byte code offset 0
  2. BoundMethodHandle.arg(), at byte code offset 17
Byte code of method BoundMethodHandle.bindSingle()


Byte code of method BoundMethodHandle.arg()

Highlight: Source code of

BoundMethodHandle.bindSingle()

:



62  static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
63      // for some type signatures, there exist pre-defined concrete BMH classes
64      try {
65          switch (xtype) {
66          case L_TYPE:
67              return bindSingle(type, form, x);  // Use known fast path.
68          case I_TYPE:
69              return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(I_TYPE_NUM).factory().invokeBasic(type, form, ValueConversions.widenSubword(x));
70          case J_TYPE:
71              return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(J_TYPE_NUM).factory().invokeBasic(type, form, (long) x);
72          case F_TYPE:
73              return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(F_TYPE_NUM).factory().invokeBasic(type, form, (float) x);
74          case D_TYPE:
75              return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(D_TYPE_NUM).factory().invokeBasic(type, form, (double) x);
76          default : throw newInternalError("unexpected xtype: " + xtype);
77          }
78      } catch (Throwable t) {
79          throw uncaughtException(t);
80      }
81  }

Highlight: Source code of

BoundMethodHandle.arg()

:



178  /*non-public*/ final Object arg(int i) {
179      try {
180          Class fieldType = speciesData().fieldTypes().get(i);
181          switch (BasicType.basicType(fieldType)) {
182              case L_TYPE: return          speciesData().getter(i).invokeBasic(this);
183              case I_TYPE: return (int)    speciesData().getter(i).invokeBasic(this);
184              case J_TYPE: return (long)   speciesData().getter(i).invokeBasic(this);
185              case F_TYPE: return (float)  speciesData().getter(i).invokeBasic(this);
186              case D_TYPE: return (double) speciesData().getter(i).invokeBasic(this);
187          }
188      } catch (Throwable ex) {
189          throw uncaughtException(ex);
190      }
191      throw new InternalError("unexpected type: " + speciesData().key()+"."+i);
192  }

So we can found that, the key reason for the compiler to generate the

BoundMethodHandle$1.class

class, and its

$SwitchMap$java$lang$invoke$LambdaForm$BasicType

field is, there is an

switch

statment on the

LambdaForm.BasicType

value.

Here is the highlighted source code of the LambdaForm.BasicType:



139  enum BasicType {
140      L_TYPE('L', Object.class, Wrapper.OBJECT),  // all reference types
141      I_TYPE('I', int.class,    Wrapper.INT),
142      J_TYPE('J', long.class,   Wrapper.LONG),
143      F_TYPE('F', float.class,  Wrapper.FLOAT),
144      D_TYPE('D', double.class, Wrapper.DOUBLE),  // all primitive types
145      V_TYPE('V', void.class,   Wrapper.VOID);    // not valid in all contexts
...
155      static final byte
156              L_TYPE_NUM = (byte) L_TYPE.ordinal(),
157              I_TYPE_NUM = (byte) I_TYPE.ordinal(),
158              J_TYPE_NUM = (byte) J_TYPE.ordinal(),
159              F_TYPE_NUM = (byte) F_TYPE.ordinal(),
160              D_TYPE_NUM = (byte) D_TYPE.ordinal(),
161              V_TYPE_NUM = (byte) V_TYPE.ordinal();

And we can easily double confirm it is indeed the source code for the generated

class contructor

logic of

BoundMethodHandle$1.class

.

Call graph of BoundMethodHandle$1.class class constructor


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4