因此,在 Java 中,构造函数的第一行必须是对 super 的调用……无论是隐式调用 super(),还是显式调用另一个构造函数。我想知道的是,为什么我不能在它周围放置一个 try 块?
我的具体情况是我有一个模拟课程用于测试。没有默认的构造函数,但我想要一个使测试更易于阅读的构造函数。我还想将从构造函数抛出的异常包装到 RuntimeException 中。
所以,我想做的实际上是:
public class MyClassMock extends MyClass {
public MyClassMock() {
try {
super(0);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Mocked methods
}
但 Java 抱怨 super 不是第一个语句。
我的解决方法:
public class MyClassMock extends MyClass {
public static MyClassMock construct() {
try {
return new MyClassMock();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public MyClassMock() throws Exception {
super(0);
}
// Mocked methods
}
这是最好的解决方法吗?为什么 Java 不让我做前者?
对于“为什么”,我最好的猜测是 Java 不想让我有一个处于潜在不一致状态的构造对象......但是,在进行模拟时,我并不关心这一点。看来我应该能够做到上述操作...或者至少我知道上述操作对于我的情况是安全的...或者看起来无论如何都应该如此。
我将覆盖测试类中使用的任何方法,因此不存在使用未初始化变量的风险。
不幸的是,编译器无法按照理论原则工作,即使您可能知道它在您的情况下是安全的,如果他们允许的话,它对于所有情况都必须是安全的。
换句话说,编译器不仅会阻止您,还会阻止所有人,包括所有不知道它不安全且需要特殊处理的人。可能还有其他原因,因为所有语言通常都有办法做到这一点unsafe事情,如果一个人知道如何处理它们。
在 C# .NET 中也有类似的规定,声明调用基构造函数的构造函数的唯一方法是:
public ClassName(...) : base(...)
这样做时,将在构造函数主体之前调用基本构造函数,并且您无法更改此顺序。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)