When a
.class
file marked with the
ACC_SYNTHETICflag, it indicates the
.class
file was generated by
compilerand 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:
BoundMethodHandle$1.class
UML diagram of BoundMethodHandle$1.class
And this class is used by the container class
BoundMethodHandle:
Dependency Network diagram ofBoundMethodHandle$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:
BoundMethodHandle.bindSingle()
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$BasicTypefield is, there is an
switchstatment on the
LambdaForm.BasicTypevalue.
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 contructorlogic of
BoundMethodHandle$1.class.
Call graph ofBoundMethodHandle$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