我指着一些窍门,发现了这一点。在以下代码中:
public class TestClass1 {
static int a = 10;
public static void main(String ar[]){
TestClass1 t1 = null ;
System.out.println(t1.a); // At this line
}
}
t1
对象是null
。为什么这段代码没有抛出NullPointerException
?
我知道这不是访问static
变量的正确方法,但问题在于NullPointerException
。
如果要使用以下方法反汇编您的班级文件,请向当前答案中添加一些其他信息:
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
}
在这里,您可以看到该getstatc
指令在第7行完成了对静态字段的访问。每当通过代码访问静态字段时,getstatic
都会在.class
程序文件中生成相应的指令。
*static
指令具有特殊性,即它们不需要在调用它们之前就对要在堆栈中的对象实例进行引用(例如,invokevirtual确实需要在堆栈中引用对象),它们仅使用字段来解析字段/方法运行时常量池的索引,以后将用于解决字段引用位置。
这是技术警告的原因,因为在编写时某些IDE会向您抛出 “应该以静态方式访问静态字段” 的警告t1.a
,因为对象实例对于解析静态字段是不必要的。
静态变量属于类本身,在类加载的时候就会分配内存,可以通过类名直接访问; 非静态变量属于类的对象,只有在类的对象产生时,才会分配内存,通过类的实例去访问; 静态方法也属于类本身,但是此时没有类的实例,内存中没有非静态变量,所以无法调用。
问题内容: 为什么我们可以通过Java中的对象引用访问静态变量,如下面的代码? 问题答案: 通常,每个人都可以访问公共变量,并且只能从该类的当前实例内部访问私有变量。在您的示例中,您被允许从方法中访问变量,因为该方法在Static类内。 如果您想知道为什么为什么要允许您从静态类的另一个实例(而不是当前实例)访问它(通常不允许使用私有变量),这仅仅是因为静态变量不存在于静态类中。每个实例,但每个班级
问题内容: 考虑这个例子: 允许您通过反射来访问类的私有字段似乎是不合逻辑的。为什么有这样的功能?允许这样的访问不是“危险”吗? 问题答案: 专用旨在防止意外滥用,而不是作为一种安全机制。如果您选择绕过它,那么您可以自行承担风险,并假设您知道自己在做什么。
问题内容: 我已经开始学习用于Android应用程序开发的Java语言。 根据我对静态类的理解,我们无法实例化静态类的对象。 但是,为什么在随后的情况下允许实例化静态嵌套类对象? 如果将内部类的对象标记为静态,为什么我们可以创建它呢? 问题答案: 根据我对静态类的理解,我们无法实例化静态类的对象。 您对“静态类”的含义的理解不正确。基本上, Java中 的“静态类” 是嵌套类,它没有对包含类的实例
我已经阅读了许多关于堆栈溢出的文章,试图找出为什么下面的代码1不起作用,但代码2起作用。我发现在6版和7版的不同版本中,行为或编译器存在不一致性https://stackoverflow.com/questions/13864464/use-of-uninitialized-final-field-with-without-this-qualifier.这更多地涉及访问默认的最终变量,无论是否有“
但是为什么在下面的情景中允许静态嵌套类对象的实例化呢? 为什么我们可以创建内部类的对象,如果它被标记为静态的?