Java 为什么在这里工作而在这里不工作?
Java 为什么在这里工作而在这里不工作?,java,Java,为什么第8行可以工作,即使“out”引用为null,而在第9行,我做了另一个与引用“out”相同的引用(类型为“PrintStream”的静态final,值为null)不能工作,我得到了“NullPointerException”?系统。out有点神奇。尽管它是final并用null初始化,但它实际上具有非null值 之所以发生这种情况,是因为JVM对该字段(以及其他一些字段)进行了特殊处理 你不能用纯java复制这种行为,你需要使用不安全的魔法。我认为你的第二张图片显示的是java.lang.
为什么第8行可以工作,即使“out”引用为null,而在第9行,我做了另一个与引用“out”相同的引用(类型为“PrintStream”的静态final,值为null)不能工作,我得到了“NullPointerException”?
系统。out
有点神奇。尽管它是final
并用null
初始化,但它实际上具有非null值
之所以发生这种情况,是因为JVM
对该字段(以及其他一些字段)进行了特殊处理
你不能用纯java复制这种行为,你需要使用不安全的魔法。我认为你的第二张图片显示的是
java.lang.System
的代码片段
我想你是在问“为什么System.out.println
在System.out
为final
并初始化为null
的情况下仍然有效?”
答案是<强大>魔法强>
JVM初始化中有一些深层次的魔法,将非空值重新分配给System.in
、System.out
和System.err
。事实上,Java语言规范中甚至提到了这些字段的特殊性(如果您好奇的话)
类似的魔法也被用来使系统。出发(…)
和朋友们工作
依我看,最好是相信它是有效的。。。不要问怎么做
由此推论,您尝试执行类似操作失败的原因是
x
字段的行为符合预期。它已初始化为null
,并保持这种状态。这里没有魔法。你的代码不是“特殊的”
(值得一提的是,在某些情况下,可以使用反射来修改
final
字段的值。但这不是一个好主意。首先,JLS没有仔细说明执行此操作时会发生什么;请参见。)请将代码作为文本发布在此处。这不是典型的NPE问题。请相信我……@luk2302这是final
字段,因此有理由认为该值不会改变。在本例中,它发生了变化,但这只是因为JVM
magic这样您就可以看到System.out不是空的,但是当您进行调用时,x是空的。
public class Main {
public static final PrintStream x = null;
public static void main(String[] args) {
/*Line 8*/ System.out.println("Da");
/*Line 9*/ x.println("Da");
}
}