Java 如何阻止编译器将单元化对象作为错误读取

Java 如何阻止编译器将单元化对象作为错误读取,java,object,null,Java,Object,Null,我有eclipse,当我尝试查看一个未初始化的对象是否等于null时,它不允许我,它会出现一个“x可能未初始化”错误,我知道它应该可以工作 举例说明我的意思: Object obj; System.out.println(obj==null ? "no value":"has a value"); 它不会编译,它会说“obj可能还没有初始化”。我如何在eclipse中更改编译器设置来解决这个问题?您不需要在eclipse中更改编译器设置来解决这个问题:您只需初始化变量o

我有eclipse,当我尝试查看一个未初始化的对象是否等于null时,它不允许我,它会出现一个“x可能未初始化”错误,我知道它应该可以工作

举例说明我的意思:

      Object obj;
      System.out.println(obj==null ? "no value":"has a value");

它不会编译,它会说“obj可能还没有初始化”。我如何在eclipse中更改编译器设置来解决这个问题?

您不需要在eclipse中更改编译器设置来解决这个问题:您只需初始化变量
obj

      Object obj = null;
      System.out.println(obj==null ? "no value":"has a value");
从:

局部变量(§14.4,§14.14)在使用前必须通过初始化(§14.4)或赋值(§15.26)明确给定一个值,其方式可以使用明确赋值规则(§16)进行验证

如果你真的不想初始化obj,你需要让它成为一个类的成员而不是一个局部变量。然后它将有一个默认的初始值:(同样,请参阅)


。。。但在引擎盖下,它仍在初始化。

这是一个局部变量,您需要使用以下命令初始化它:

Object obj = null;
虽然类、对象和数组的某些字段可能会隐式初始化为有用的默认值,但局部变量并非如此

JLS7
16.2.4
Local variable declaration statements
)部分是您想要理解的部分,但需要一些时间才能理解,它相当迟钝:-)

您可能希望从第16节的顶部开始(
definiteassignment
)并从那里开始工作。这篇文章的第一部分有两段,在这里最为贴切(我用斜体字强调):

对于每次访问局部变量或空白
final
字段
X
X
必须在访问之前明确分配,否则会发生编译时错误

当且仅当 变量(或者,对于字段,其简单名称由
this
限定)出现在左侧 赋值运算符的一侧


编译器显示错误,因为规则是所有局部变量必须在首次读取之前初始化。因此,首先声明局部变量而不初始化它,稍后初始化它,然后使用它:

Object obj = null;

 System.out.println(obj==null ? "no value":"has a value");
如何在eclipse中更改编译器设置以修复此问题

你不能。Java语言规范要求任何一致的Java编译器将其视为编译错误

没有Eclipse编译器设置导致它违反此规则

即使(假设)有这样的设置,我认为当JVM试图加载字节码文件时,字节码文件的验证也会失败。(如果您能以某种方式诱使JVM使用未初始化的局部变量的值,这将破坏运行时类型的安全性,导致JVM崩溃……甚至更糟。)


如果
obj
是一个实例变量而不是一个局部变量,那么它将默认初始化为
null
,并且不会出现编译错误。但是局部变量不是默认初始化的

如何在eclipse中更改编译器设置以修复此问题


解决方案是修复代码。此错误的目的是检测和防止错误。采取步骤允许编译损坏的代码通常是一个非常糟糕的主意。

字段,即类定义中的变量,被初始化为null或0或类型的默认值。方法中定义的局部变量未初始化为默认值。空值与未初始化不同。好的,谢谢。Idk由于某种原因,我认为java中的对象在没有初始化的情况下是空的。无论如何,我都是这样做的,但我一直听说我不需要obj=null。因此,感谢您让我放心。对于作为类成员的变量(静态变量或实例变量),它们的初始化值为
null
。必须初始化局部变量。我链接到规范,如果你想阅读更多。
Object obj = null;

 System.out.println(obj==null ? "no value":"has a value");