Not*_*bug 27 java static javac nullpointerexception
我指着一些技巧并遇到了这个.在以下代码中:
public class TestClass1 {
static int a = 10;
public static void main(String ar[]){
TestClass1 t1 = null ;
System.out.println(t1.a); // At this line
}
}
Run Code Online (Sandbox Code Playgroud)
t1
对象是null
.为什么这段代码不抛NullPointerException
?
我知道这不是访问static
变量的正确方法,但问题是关于NullPointerException
.
Sur*_*tta 27
调用静态成员或方法时不需要实例.
由于静态成员属于类而不是实例.
空引用可用于访问类(静态)变量而不会导致异常.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#d5e19846
如果你看到这个例子(参见规范中的完整示例)
public static void main(String[] args) {
System.out.println(favorite().mountain); //favorite() returns null
}
Run Code Online (Sandbox Code Playgroud)
即使favorite()的结果为null,也不会抛出NullPointerException.打印"Mount"表明主表达式确实在运行时完全评估,尽管事实上只使用其类型而不是其值来确定要访问的字段(因为字段山是静态的).
hig*_*aro 11
要向当前答案添加一些其他信息,如果您使用以下方法反汇编类文件:
javap -c TestClass1
Run Code Online (Sandbox Code Playgroud)
你会得到:
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
}
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到通过getstatc
指令在第7行完成对静态字段的访问.每当通过代码访问静态字段时,getstatic
将在.class
程序文件中生成相应的指令.
*static
指令具有这样的特殊性:在调用它们之前,它们不需要在堆栈中引用对象实例(例如,在堆栈中需要对象引用的invokevirtual),它们仅使用just解析字段/方法运行时常量池的索引,稍后将用于求解字段引用位置.
这是警告"静态字段应该以静态方式访问"的技术原因,一些IDE在您编写时会向您抛出t1.a
,因为对象实例不需要解析静态字段.
归档时间: |
|
查看次数: |
4810 次 |
最近记录: |