在构造函数中使用 'this' 而不抛出 NullPointerException

Using 'this' in constructors without throwing a NullPointerException

我想创建一个 class Bar 这样每次我实例化一个 Bar 时,它都会被添加到对象 [=15= 的 ArrayList<Bar> ].这是我试过的:

class Foo {
    private ArrayList<Bar> bars;
    .
    .
    .
    public ArrayList<Bar> getBars() { return bars; }
}

//in class Bar
class Bar {
    public Bar(Foo f) {
        f.getBars().add(this); //NullPointerException!
    }
}

我意识到这里发生了什么(构造函数没有完成,所以this returns null),但我怎样才能避免这种情况?

I realize what is happening here (the constructor is not finished, so this returns null), but how can I avoid this?

您的诊断不正确。

this 的值永远不能是 null。这包括在构造函数中。

JLS (15.8.3) 声明如下:

"The keyword this may be used only in the body of an instance method or default method, or in the body of a constructor of a class, or in an instance initializer of a class, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs."

"When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method or default method was invoked (§15.12), or to the object being constructed."

如您所见:

  1. this关键字只能出现在当前对象的上下文中,并且

  2. this(用作表达式时)的值始终是对当前对象的引用;没有提到任何可能 null.

    的情况

(另请参阅:Can "this" ever be null in Java?


this 引用的对象此时未完全初始化,但这不是您所看到的异常的原因。 NPE 的原因是别的。

具体来说,如果在该行抛出 NPE,则 fnull f.getBars() 返回 null。看看你如何编码 Foo class,后者绝对是合理的。 (您没有初始化 bars 成员...所以它将是 null。)

因为bars没有初始化,所以每当你调用f.getBars()它returns一个null对象。当您尝试在 null 对象上调用 .add() 时,您会得到一个 NullPointerException.

改变

private ArrayList<Bar> bars;

private ArrayList<Bar> bars = new ArrayList<Bar>();

或添加

public Foo(){this.bars = new ArrayList<Bar>();}

给你的 Foo class.