未初始化变量和成员的Java未初始化变量和成员的Java(Uninitialized variabl

2019-05-10 09:57发布

试想一下:

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”,这是一个编译时错误。 为什么本地变量和成员之间的区别?

编辑 :使会员私人是我的初步意向,问题仍然有效...

Answer 1:

对于明确赋值的规则是相当困难的(读JLS第3版的第16章)。 这是不实际执行上的字段明确赋值。 既然这样,它甚至有可能它们被初始化之前,观察最终的领域。



Answer 2:

语言定义了这种方式。

到对象类型默认的实例变量初始化为null。 对象类型的局部变量默认情况下不进行初始化,这是一个编译时错误访问未定义的变量。

见4.5.5在这里http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.5



Answer 3:

这里的交易。 你打电话的时候

TestClass tc = new TestClass();

new命令执行了四个重要的任务:

  1. 分配在堆新对象存储。
  2. 启动类字段为默认值(数值运算到0,布尔值, false ,对象null )。
  3. 调用构造方法(可以重新启动域,也可能不会)。
  4. 返回新对象的引用。

所以,你的域“A”和“B”都开始向null ,而“A”是在构造函数重新启动。 这个过程是不相关的方法调用,所以局部变量的“C”是永远不会初始化。

HTH

PS:对于严重失眠,看了这个 。



Answer 4:

编译器可以找出是c决不会被设置。 b变量可能是因为有人在构造函数被调用后,其他DoSomething的()之前进行设置,但是。 做B私人和编译器可能能够帮助。



Answer 5:

编译器可以从DoSomething的()的代码将c声明那里,从来没有初始化告诉。 因为它是本地的,也没有可能性,它在其他地方初始化。

它不能告诉何时或何地,你要调用DoSomething的()。 b是公共成员。 这是完全有可能你会调用方法前初始化其他代码。



Answer 6:

成员变量初始化为null或到其默认的原始值,如果他们是原语。

局部变量是不确定的,而不是初始化,您负责设置初始值。 编译器会阻止您使用它们。

因此,b为当在c是未定义类的TestClass被实例初始化。

注:空是不确定的不同。



Answer 7:

实际上,你已经确定了在通常试图在编辑发现错误Java的系统更大的孔中的一个/编译时间,而不是运行,因为时间 - 作为公认的答案说 - 这是很难说如果b初始化。

有几个方式来解决这一缺陷。 首先是“默认决赛”。 如果你的成员是最终的,你就必须填补他们与构造 - 它会使用路径分析,以确保每一个可能的路径在总决赛中填充(你仍然可以为其分配“空”,这会破坏的目的,但至少你将不得不承认,你是有意这样做)。

第二种方法是严格的空检查。 您可以通过项目或默认属性打开它在Eclipse中设置。 我相信它会迫使你为null检查你的b.notify()调用它。 这可以迅速得到失控,所以它往往会去一组注解,使事情变得更简单:

一旦你打开严格无效检查和注释变量的类型是“可空”和“NOTNULL”的注释可能有不同的名称,但在概念上。 如果你尝试将可空放置到一个非空的变量,你必须首先检查它的空。 参数和返回类型也注释,这样你就不必检查null分配给一个非空变量每一次。

还有一个“NotNullByDefault”包级别的注释,这将使编辑认为没有变量永远不会有一个空值,除非你将其标记为空。

这些注解大多应用在编辑器的水平 - 你可以月食,可能其他编辑器中打开它们 - 这就是为什么他们不一定标准化。 (至少我最后一次检查,爪哇8可能有一些注释我还没有发现尚)



文章来源: Uninitialized variables and members in Java