要向当前答案添加一些其他信息,如果您使用以下命令反汇编类文件:
javap -c TestClass1
您将获得:
Compiled from "TestClass1.java"
public class TestClass1 extends java.lang.Object{
static int a;
public TestClass1();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
5: aload_1
6: pop
7: getstatic #3; //Field a:I
10: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
13: return
static {};
Code:
0: bipush 10
2: putstatic #3; //Field a:I
5: return
}
在这里,您可以看到对静态字段的访问是通过指令在第7行完成的。每当通过代码访问静态字段时,都会在程序文件中生成相应的 getstatic
指令。getstatc
.class
*static
指令的特殊性在于,在调用它们之前,它们不需要对堆栈中的对象实例的引用(例如,invokevirtual 确实需要在堆栈中提供对象引用),它们仅使用运行时常量池的索引来解析字段/方法,该索引稍后将用于求解字段引用位置。
这是某些 IDE 在编写 时会向您抛出的警告“应以静态方式访问静态字段”的技术原因,因为对象实例不需要解析静态字段。t1.a