我有一个Java 7代码,我正在玩MethodHanlde。代码是:
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
class HelloWorldApp {
public static void main(String[] args) {
MyMethodHandle obj = new MyMethodHandle();
obj.getToStringMH();
}
}
class MyMethodHandle {
public String getToStringMH() {
MethodHandle mh;
String s ;
MethodType mt = MethodType.methodType(String.class, char.class, char.class);
MethodHandles.Lookup lk = MethodHandles.lookup();
try {
mh = lk.findVirtual(String.class, "replace", mt);
} catch (NoSuchMethodException | IllegalAccessException mhx) {
throw (AssertionError)new AssertionError().initCause(mhx);
}
try {
s = (String) mh.invokeExact("daddy",'d','n');
}
catch(Exception e) {
throw (AssertionError)new AssertionError().initCause(e);
}
System.out.println(s);
return "works";
}
}
编译时:
javac HelloWorldApp.java
我收到这样的错误:
HelloWorldApp.java:23: error: unreported exception Throwable; must be caught or declared to be thrown
s = (String) mh.invokeExact("daddy",'d','n');
^
1 error
我在哪里弄错了?
答案 0 :(得分:5)
作为MethodHandle.invokeExact州的Javadoc
public final Object invoke(Object... args) throws Throwable
这意味着你会抓住或“抛出”Throwable
BTW因为这会抛出一个通用异常,而不是
try {
s = (String) mh.invokeExact("daddy",'d','n');
} catch(Throwable t) {
throw new AssertionError(t);
}
是用
重新抛出Throwable try {
s = (String) mh.invokeExact("daddy",'d','n');
} catch(Throwable t) {
Thread.currentThread().stop(t); // avoids wrapping the true exception
}
如果你停止另一个线程,使用Thread.stop(t)可能是不可预测的。如果你把它扔给当前的线程是可以预测的。
注意:您需要确保您的方法“抛出”您正在调用的方法的相应检查异常,因为编译器无法确保这种情况。
答案 1 :(得分:1)
invokeExact
被声明为throws Throwable
。因此,您需要捕获Throwable
而不是Exception
。 (Exception
只是Throwable
中的一种。)
try {
s = (String) mh.invokeExact("daddy",'d','n');
}
catch(Throwable t) {
throw new AssertionError(t);
}