从匿名内部类的构造函数中抛出异常

时间:2014-12-07 01:59:43

标签: java exception constructor anonymous-inner-class throws

如何添加" throws"一个匿名的内部类的构造函数?

class Foo {
  public Foo() throws Exception {
  }
}

认为这不起作用

 public static void main(String[] args) {
   Foo x = new Foo() {
     @Override
     public Foo() throws Exception {
     }
   }
 }

我试图弄清楚"投掷的位置"抑制编译器警告。有没有办法在不使用try / catch块或单独创建类的情况下执行此操作?

4 个答案:

答案 0 :(得分:4)

我不确定你想要完成什么。请注意,匿名类永远不会有显式声明的构造函数。这是可以理解的,因为如果它有一个,它需要有一个名字,因此不再是匿名。

如果你想拥有一个构造函数可能抛出的类的匿名子类,这不是问题。

class Foo {
    Foo() throws Exception {
    }
}

void demo() throws Exception {
    Foo foo = new Foo() {  // might throw
    };
}

同样,如果你想用可能引发的东西初始化匿名类,你也可以这样做。请记住,匿名类的定义是表达式,因此只要它们被try - catch块包围,它们就可以抛出,或者contains方法声明要抛出的异常。

class Foo {
}

class Bar {
    Bar() throws Exception {
    }
}

void demo() throws Exception {
    Foo foo = new Foo() {
        Bar bar = new Bar();  // might throw
    };
}

答案 1 :(得分:1)

您不能在匿名类上声明构造函数。

从Java语言规范第15.9.5.1节“匿名构造函数”:匿名类不能有显式声明的构造函数。

如果您需要一个新的构造函数,请将该类设为内部类(但不是匿名),甚至是顶级类。

答案 2 :(得分:0)

如果确实需要强制执行匿名类实例的一致性,则可以在工厂方法中创建它们,如果参数无效,则抛出异常。这仅适用于接口的匿名实例,因为匿名类不能是方法的返回类型。

一个毫无意义的例子:

public class AnonymousException {

    public static void main(String args) {
        newRunnable(42).run();
    }

    private static Runnable newRunnable(final int x) {
        if(x < 0) throw new IllegalArgumentException();
        return new Runnable() {
            @Override
            public void run() {
                System.out.println("x=" + x);
            }
        };
    }
}

答案 3 :(得分:0)

  

我正在试图找出将“throws”放在哪里来抑制编译器警告。

使用throws无法做到这一点。匿名语法不允许您在(隐式)构造函数上放置throws子句。 (隐式)构造函数隐式抛出您正在使用的所有超类构造函数。 (这取决于参数的数量和类型......)

除此之外:即使它确实设法做到了这一点,throws子句也不会抑制我怀疑你得到的编译错误。从根本上说,超类构造函数声明它可能抛出Exception并且添加throws无法改变那个事实...没有某种方法来处理超类构造函数异常。

  

有没有办法在不使用try / catch块或单独创建类的情况下执行此操作?

不,没有。

我怀疑你正在尝试做的事情甚至不可能有一个常规的超类/子类。例如:

public class Foo {
    public Foo(int i) throws Exception { }
}

public class Bar extends Foo {
    public Bar(int i) {
        super(i);
    }
}

没有办法让它编译,因为Bar构造函数无法抑制或处理Foo构造函数声明它抛出的异常。

(并且有一个合理的原因。如果Foo(42)确实抛出异常,那么当异常到达Bar构造函数时,它将不得不部分地处理的状态构建 Foo。这是不切实际的,即使是这样,也不是一个好主意。)