我有两节课:
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;
}
}
不幸的是,没有内置的 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)。