what is a synthetic field and method

if you overview the bytecode of a java class file, maybe you will find a keyword synthetic which is not include in the keyword of java language. so when will synthetic come out in the bytecode in a class file?

 Any constructs introduced by the compiler that do not have a corresponding construct in the source code must be marked as synthetic, except for default constructors and the class initialization method.[1]

it means when there is a field or method introduced into a class file by the compiler and we can not find the primary declaration in the source file, it will marked as synthetic. let us have a look at a simple example.

public class A{
 private int aSynthetic;
 public int noSynthetic;
 class B{
 public void test(){
 System.out.println(aSynthetic);
 System.out.println(bSynthetic);
 }
 }
}
so let's see what the compiler output:
// Compiled from A.java (version 1.6 : 50.0, super bit)
public class A {

 // Field descriptor #6 I
 private int aSynthetic;

 // Field descriptor #6 I
 public int noSynthetic;

 // Method descriptor #9 ()V
 // Stack: 1, Locals: 1
 public A();
 0 aload_0 [this]
 1 invokespecial java.lang.Object() [11]
 4 return
 Line numbers:
 [pc: 0, line: 24]
 Local variable table:
 [pc: 0, pc: 5] local: this index: 0 type: A

 // Method descriptor #18 (LA;)I
 // Stack: 1, Locals: 1
 static synthetic int access$0(A arg0);
 0 aload_0
 1 getfield A.aSynthetic : int [19]
 4 ireturn
 Line numbers:
 [pc: 0, line: 25]

 Inner classes:
 [inner class info: #24 A$B, outer class info: #1 A
 inner name: #26 B, accessflags: 0 default]
}
// Compiled from A.java (version 1.6 : 50.0, super bit)
class A$B {

 // Field descriptor #6 LA;
 final synthetic A this$0;

 // Method descriptor #8 (LA;)V
 // Stack: 2, Locals: 2
 A$B(A arg0);
 0 aload_0 [this]
 1 aload_1
 2 putfield A$B.this$0 : A [10]
 5 aload_0 [this]
 6 invokespecial java.lang.Object() [12]
 9 return
 Line numbers:
 [pc: 0, line: 27]
 Local variable table:
 [pc: 0, pc: 10] local: this index: 0 type: A.B

 // Method descriptor #14 ()V
 // Stack: 2, Locals: 1
 public void test();
 0 getstatic java.lang.System.out : java.io.PrintStream [20]
 3 aload_0 [this]
 4 getfield A$B.this$0 : A [10]
 7 invokestatic A.access$0(A) : int [26]
 10 invokevirtual java.io.PrintStream.println(int) : void [32]
 13 getstatic java.lang.System.out : java.io.PrintStream [20]
 16 aload_0 [this]
 17 getfield A$B.this$0 : A [10]
 20 getfield A.noSynthetic : int [38]
 23 invokevirtual java.io.PrintStream.println(int) : void [32]
 26 return
 Line numbers:
 [pc: 0, line: 29]
 [pc: 13, line: 30]
 [pc: 26, line: 31]
 Local variable table:
 [pc: 0, pc: 27] local: this index: 0 type: A.B

 Inner classes:
 [inner class info: #1 A$B, outer class info: #27 A
 inner name: #45 B, accessflags: 0 default]
}
so we can find a synthetic field A this$0 which is a reference to the outer class A. it is introduced by compiler so that you can use the field in the inner class without any troubles.
also we can find 7 invokestatic A.access$0(A) : int [26] in the class B when we visit aSynthetic field but no such bytecode when we visit noSynthetic.
The reason is aSynthetic is a private field which can not be accessed outside the class A, so the compiler supply a access$0 method to visit the private field in the outer class. the 0 is a index to the field array. as the same we don't need to use such method when we access a outer class' public or protect field.
[1] The Java Language Specification 3rd

你可能感兴趣的:(what is a synthetic field and method)