IndexOutOfBoundsException抛出的UndeclaredThrowableException

时间:2013-10-30 18:09:19

标签: java proxy-classes

我正在使用List<WebElement>的装饰器模式。这部分装饰需要使用代理。

当我使用超出范围的索引调用get(index)时,它会抛出IndexOutOfBounds异常,然后由代理捕获,并用UndeclaredThrowableException包装。

我的理解是,如果它是一个已检查的异常,它应执行此操作。 IndexOutOfBounds未经检查的例外,为什么它会被包裹?

即使我将throws IndexOutOfBounds添加到invoke函数中,它仍会被包装。

这是我的代码:

@SuppressWarnings("unchecked")
public WebElementList findWebElementList(final By by){
    return new WebElementList(
            (List<WebElement>) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    new Class<?>[] { List.class }, new InvocationHandler() {
        // Lazy initialized instance of WebElement
        private List<WebElement> webElements;

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            if (webElements == null) {
                webElements = findElements(by);
            }
            return method.invoke(webElements, args);
        }
    }), driver);
}

这是我的堆栈跟踪的一部分:

java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy30.get(Unknown Source)
at org.lds.ldsp.enhancements.WebElementList.get(WebElementList.java:29)
...
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
... 41 more

2 个答案:

答案 0 :(得分:9)

Vic Jang是对的。您需要在try-catch中包装调用并重新抛出内部异常。

try {
  return method.invoke(webElements, args);
} catch (InvocationTargetException ite) {
  throw ite.getCause();
}

原因是&#34; Method.invoke&#34;在InvocationTargetException中包装那些在方法代码中抛出的异常。

<强> java.lang.reflect.Method中:

  

抛出:
  ...
  InvocationTargetException - 如果是基础方法   抛出异常。

<强> java.lang.reflect.InvocationTargetException:

  

InvocationTargetException是一个包装了一个的已检查异常   被调用的方法或构造函数抛出的异常。

代理对象的类没有在其&#34; throws&#34;中声明InvocationTargetException。这导致UndeclaredThrowableException。

答案 1 :(得分:3)

我没有足够的声誉来发表评论。 您的问题似乎与this one

非常相似

您可以查看那里的解决方案,看看是否有效。

简而言之,您需要将method.invoke包裹到try{}catch例外,然后再throw