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

Posted

技术标签:

【中文标题】从匿名内部类的构造函数中抛出异常【英文标题】:Throwing an exception from an anonymous inner class's constructor 【发布时间】:2015-02-04 23:20:48 【问题描述】:

如何向匿名内部类的构造函数添加“抛出”?

class Foo 
  public Foo() throws Exception 
  

因为这不起作用

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

我正在尝试找出“抛出”的位置以抑制编译器警告。有没有办法在不使用 try/catch 块或创建单独的类的情况下做到这一点?

【问题讨论】:

在我输入完之前不小心按了回车,我已经得到了-2。 是的,有时人们会比你想象的更快更频繁地打你一巴掌,而且经常没有告诉你原因。 Accessing constructor of an anonymous class的可能重复 【参考方案1】:

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

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

class Foo 
    Foo() throws Exception 
    


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

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

class Foo 


class Bar 
    Bar() throws Exception 
    


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

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

如果我仍然想把它放在一个匿名的内部类中,我是否必须使用 try/catch 块,或者有其他方法吗? 您所指的“它”是什么?构造函数? 取决于您的代码是否实际抛出。由于 Foo 被声明为抛出,因此最好使用 try / catch 块。【参考方案3】:

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

一个完全没有意义的例子:

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);
            
        ;
    

【讨论】:

【参考方案4】:

我正在尝试找出“抛出”的位置以抑制编译器警告。

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。这是不实际的,即使是这样,也是个坏主意。)

【讨论】:

以上是关于从匿名内部类的构造函数中抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

java中匿名内部类的匿名构造函数是怎么用的?

匿名类的定义,使用场景和使用方式

匿名内部类

JAVA学习之局部内部类,匿名内部类,静态内部类

匿名内部类

该如何理解匿名内部类的功能?