问题

所以,在Java中,您的构造函数HAS的第一行是对super的调用...无论是隐式调用super()还是显式调用另一个构造函数.我想知道的是,为什么我不能围绕这个设置一个尝试块?

我的具体情况是我有一个测试的模拟类.没有默认构造函数,但我想让一个更简单地读取测试.我还想将构造函数抛出的异常包装到RuntimeException中.

所以,我想做的是有效地这样做:

 public class MyClassMock extends MyClass {
    public MyClassMock() {
        try {
            super(0);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // Mocked methods
}
 

但Java抱怨超级语句不是第一个语句.

我的解决方法:

 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不想让我有一个可能不一致的状态的构造对象...但是,在进行模拟时,我不在乎这一点.似乎我应该能够做到上述....或者至少我知道上面的内容对我的情况来说是安全的.....或者似乎应该是无论如何的.

我正在覆盖我从测试类中使用的任何方法,所以我没有使用未初始化变量的风险.

  最佳答案

不幸的是,编译器无法在理论原则上工作,即使你可能知道它在你的情况下是安全的,如果他们允许的话,它必须对所有情况都是安全的。

换句话说,编译器不仅仅停止你,它正在阻止每个人,包括那些不知道它是不安全的,需要特殊处理的人.这可能还有其他原因,如果知道如何处理它们,所有语言通常都有办法做不安全的事情.

在C#.NET中有类似的规定,声明调用基础构造函数的构造函数的唯一方法是:

 public ClassName(...) : base(...)
 

在这样做的时候,基本构造函数将在构造函数的正文之前调用,您不能更改这个顺序。

  相同标签的其他问题

javaexceptionmockingtry-catch