我正在尝试Proxy
,已实施InvocationHandler
:
public interface IDataInterface {
public Future<String> getFuture();
}
public class MyData implements IDataInterface {
private String data = "abc";
@Override
public Future<String> getFuture() {
Callable<String> callMe = () -> {
TimeUnit.SECONDS.sleep(5);
return data;
};
FutureTask<String> task = new FutureTask<String>(callMe);
task.run(); // must call run(), or it will block forever!
return task;
}
}
public class MyInvocationHandler implements InvocationHandler {
private final Object delegate;
private final ExecutorService scheduler;
public MyInvocationHandler(Object obj) {
this.delegate = obj;
scheduler = Executors.newCachedThreadPool();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.printf("[Proxy] Will call method: %s\n", method.getName());
Object result = null;
if(Future.class.isAssignableFrom(method.getReturnType())) {
Callable<Object> methodRequest = () -> {
Object res = method.invoke(delegate, args);
return res;
};
Future<Object> future = scheduler.submit(methodRequest);
scheduler.shutdown();
result = future;
} else {
result = method.invoke(delegate, args);
}
// this will cause definite loop!
// Object result = method.invoke(proxy, args);
System.out.println("[Proxy] After method call.");
return result;
}
}
在main方法中,我运行:
IDataInterface myData = (IDataInterface)Proxy.newProxyInstance(
IDataInterface.class.getClassLoader(),
new Class<?>[] { IDataInterface.class },
new MyInvocationHandler(new MyData()));
Future<String> future = myData.getFuture();
try {
System.out.println(future.get().toString());
} catch(InterruptedException | ExecutionException e) {
e.printStackTrace();
}
得到以下异常java.util.concurrent.FutureTask cannot be cast to java.lang.String
:
[Proxy] Will call method: getFuture
[Proxy] Method return type is Future.
[Proxy] After method call.
Get data.Exception in thread "main" java.lang.ClassCastException: java.util.concurrent.FutureTask cannot be cast to java.lang.String
at others.proxy.Main.main(Main.java:19)
根本原因是什么?
答案 0 :(得分:1)
根本原因在于:
if(Future.class.isAssignableFrom(method.getReturnType())) {
Callable<Object> methodRequest = () -> {
Object res = method.invoke(delegate, args);
return res;
};
Future<Object> future = scheduler.submit(methodRequest);
scheduler.shutdown();
result = future;
}
Callable<Object> methodRequest (...)
将返回FutureTask<String>
Future<Object> future = scheduler.submit(methodRequest)
将返回Future<FutureTask<String>>
更改主要功能,您将看到
Future future = myData.getFuture();
try {
Future<String> future1 = (Future<String>) future.get();
System.out.println(future1.get().toString());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}