在Java中,在构造函数中调用super(...)时避免空引用

问题描述 投票:0回答:1

我有两节课:

abstract class MySuperClass {
    private final Object mySuperField;
    MySuperClass(Object myField) {
        this.mySuperField = myField;
    }
    public Object getMySuperField() {
        return mySuperField;
    }
}
public class MySubClass extends MySuperClass {
    private final Object mySubField;
    public MySubClass(MySubClass toCopy) {
        super(toCopy.getMySuperField());
        this.mySubField = toCopy.mySubField;
    }
}

MySubClass
有一个复制构造函数,如上所示。

如果

NullPointerException
参数是
MySubClass
,我想避免在
toCopy
构造函数中抛出
null
,或者至少抛出我自己的异常,但是当然,对
super(...)
的调用必须是第一行在构造函数中。

在调用

super(...)
之前,我可以使用一些 Java 模式来进行自己的参数验证吗?

我尝试了一些不同的方法,但它们看起来都很丑陋/老套,比如将 null 传递到超类构造函数中,而不在超类中进行验证,然后在子类中调用

super(...)
后进行参数验证,或者使
mySuperField
中的
MySuperClass
不是最终的,并在超类中提供一个 setter。一定有更好的东西。

在我尝试过的所有方法中,这可能是最好的选择,但它仍然感觉很糟糕。

public class MySubClass extends MySuperClass {
    private final Object mySubField;
    public MySubClass(MySubClass toCopy) {
        super(toCopy == null ? null : toCopy.getMySuperField());
        if (toCopy == null) {
            // Throw my exception
        }
        this.mySubField = toCopy.mySubField;
    }
}
java constructor nullpointerexception subclass super
1个回答
0
投票

不幸的是,没有内置的 JDK 可以不使用

NullPointerException
来执行此操作(尽管如果 NPE 可以使用自定义消息,则可以使用
Objects.requireNonNull
)。

但是,这可以通过

MySubClass
中的静态方法来完成,而不需要对
MySuperClass
进行任何修改。这与
Objects.requireNonNull
类似:

public class MySubClass extends MySuperClass {

    private static Object notNull(Object obj, Throwable onNull) {
        if (obj == null) throw onNull; // onNull cannot be null
        else return obj;
    }

    private final Object mySubField;
    public MySubClass(MySubClass toCopy) {
        super(
            notNull(
                toCopy,
                new AssertionError("Replace with something that makes sense")
           ).getMySuperField()
        );
        this.mySubField = toCopy.mySubField;
    }
}

这可以通过多种方式进行改进(例如泛型),但这种实现应该是最低公分母(并且应该适用于所有 JDK)。

© www.soinside.com 2019 - 2024. All rights reserved.