【问题标题】:Java - Catching an exception from a reflectively called constructorJava - 从反射调用的构造函数中捕获异常
【发布时间】:2012-07-29 22:26:11
【问题描述】:

我正在使用反射创建一个对象。根据正在构造的实际对象,构造函数可能有一个针对特定自定义异常的 throws 声明,它很重要,我可以捕捉到这一点。

不幸的是,当我尝试将异常添加到包含反射构造的 try 块的捕获中时,代码将无法编译,因为:

“无法到达的catch块。这个异常不会从try中抛出 声明正文”

我意识到捕获基类 Exception 会起作用,事实上这对我的代码来说是可以的。但是,情况可能并非总是如此,因为其他不同的异常可能会在将来应用于其他对象,并且在 catch 中使用 instanceof 并重新抛出其他所有内容似乎并不优雅。

有没有办法表明可能会抛出此异常,以便我可以专门捕获它?

编辑:根据要求提供一些代码。由于上述原因无法编译。

try{
  Constructor<? extends Thing> constructor = getClassType().getDeclaredConstructor(SomeParameter.class);
  Thing thing = constructor.newInstance(new SomeParameter());
}
catch(FoobarException e){
  //new Thing(SomeParameter p) might throw this
}
catch(ReflectiveOperationException | IllegalArgumentException | SecurityException e){}

【问题讨论】:

  • 我认为反射不可能推断出一个方法在编译时可能会抛出什么异常——事实上,反射 API 会因此抛出它自己的异常。我什至不确定在运行时确定这一点的方法:P
  • 能看到一些代码就好了
  • 只能捕获 InvocationTargetException
  • @galuano1,我认为您应该将其发布为答案

标签: java exception reflection exception-handling


【解决方案1】:

异常将被包裹在InvocationTargetException 中。抓住它,看看原因。

【讨论】:

  • 我现在在生产系统中使用这种方法。 +1
【解决方案2】:

有没有办法表明可能会抛出此异常,以便我可以专门捕获它?

没有。

因为此时,构造函数抛出的任何异常都将被捕获,并且将在其位置抛出InvocationTargetExceptionjavadoc 简明扼要地解释如下:

抛出:[...] InvocationTargetException - 如果底层构造函数抛出异常。”

(注意它说的是“异常”,所以这适用于构造函数抛出的已检查和未检查的异常。)

所以事实上,编译器在编译错误中说的是实话。您试图捕获的已检查异常此时不可能传播。事实上,JLS 可达性规则指出代码 绝对无法访问......因此会出现编译错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2013-01-20
    • 2010-09-14
    相关资源
    最近更新 更多