Java中未初始化的变量和成员
考虑这一点:Java中未初始化的变量和成员,java,oop,variables,Java,Oop,Variables,考虑这一点: public class TestClass { private String a; private String b; public TestClass() { a = "initialized"; } public void doSomething() { String c; a.notify(); // This is fine b.notify(); // This is
public class TestClass {
private String a;
private String b;
public TestClass()
{
a = "initialized";
}
public void doSomething()
{
String c;
a.notify(); // This is fine
b.notify(); // This is fine - but will end in an exception
c.notify(); // "Local variable c may not have been initialised"
}
}
我不明白。“b”从未初始化,但将给出与“c”相同的运行时错误,这是一个编译时错误。为什么局部变量和成员之间存在差异
编辑:将成员私有化是我最初的意图,问题仍然存在……编译器可以发现永远不会设置c。在调用构造函数之后,但在doSomething()之前,其他人可以设置b变量。将b设为private,编译器可能会提供帮助。编译器可以从doSomething()的代码中看出c在那里声明,并且从未初始化过。因为它是本地的,所以不可能在其他地方初始化
它无法告诉您将在何时何地调用doSomething()。b是公共会员。在调用该方法之前,完全有可能在其他代码中对其进行初始化。该语言是这样定义的 对象类型的实例变量默认初始化为null。 默认情况下,对象类型的局部变量未初始化,访问未定义的变量是编译时错误 SE7见第4.12.5节(与SE14相同)
事情是这样的。当你打电话的时候
TestClass tc = new TestClass();
new
命令执行四项重要任务:
false
,对象为null
)null
,并且“a”在构造函数中被重新初始化。此过程与方法调用无关,因此局部变量“c”从未初始化
嗯
PS:对于严重失眠症患者,请阅读。明确指定的规则相当困难(请阅读JLS第三版第16章)。在字段上强制执行确定赋值是不实际的。目前,甚至可以在初始化最终字段之前观察它们。成员变量被初始化为null或默认的基本值(如果它们是基本值) 局部变量未定义且未初始化,您负责设置初始值。编译器阻止您使用它们 因此,当类TestClass被实例化而c未定义时,b被初始化
注意:null不同于未定义。实际上,您已经发现了Java系统中的一个较大漏洞,即通常试图在编辑/编译时而不是运行时查找错误,因为正如公认的答案所说,很难判断b是否已初始化 有一些模式可以解决此缺陷。首先是“默认为最终”。如果您的成员是final,那么您必须用构造函数填充它们——它将使用路径分析来确保每个可能的路径都填充final(您仍然可以将其指定为“Null”,这将不符合目的,但至少您会被迫承认您是故意这样做的) 第二种方法是严格的空检查。您可以在eclipse设置中按项目或默认属性打开它。我相信这会迫使您在调用b.notify()之前对其进行null检查。这可能会很快失控,因此它倾向于使用一组注释来简化操作: 注释可能有不同的名称,但在概念上,一旦启用严格的null检查,并且注释的变量类型为“null”和“NotNull”。如果您试图将Nullable放入NOTNULL变量中,则必须首先检查它是否为null。参数和返回类型也带有注释,所以您不必每次分配给NOTNULL变量时都检查null 还有一个“NotNullByDefault”包级注释,它将使编辑器假设任何变量都不能有null值,除非您将其标记为可为null
这些注释主要应用于编辑器级别——您可以在eclipse和其他编辑器中打开它们——这就是它们不一定标准化的原因。(至少上次我检查时,Java 8可能有一些我还没有找到的注释)没有,即使它是私有的,编译器也不会给出错误(反正不是我的)。同样的,私有化并不重要SE 7的相应部分是4.12.5()“甚至可以在初始化最终字段之前观察它们。”-你介意再解释一下吗?Thanks@Nathan-您可以在对象的构造函数调用中引用默认状态下的“blank”
final
字段,以及从构造函数调用的任何内容。(和其他线程,如果构造线程“发布”实例引用。)JLS 12.4.1中解释的静态变量也会出现类似问题。(这完全超出了本问答的范围)注意:对于类型为基元类型的字段,也会发生类似的情况。