英文:
How to Invoke a method that take a Callable Interface or method as parameter with java reflection
问题
假设我有一个接受 Callable 接口作为参数的方法。
使用 Java 反射,我想调用一个接受 method
作为参数的方法。
我遇到了异常:Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
。
以下展示了我的代码。
有人知道如何实现我的意图吗?
感谢您的回答!
package com.helloworld;
import android.annotation.TargetApi;
import android.os.Build;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class FinallyBlock {
public static void main(String[] args) throws Exception {
Method[] methods = FinallyBlock.class.getDeclaredMethods();
Method templateMethod = FinallyBlock.class.getDeclaredMethod("template", Callable.class);
for (Method method : methods) {
if (method.getName().equals("main") || method.getName().equals("template")) {
continue;
}
System.out.println(templateMethod.invoke(null, method));
}
}
@TargetApi(Build.VERSION_CODES.O)
private static <T> T template(Callable<T> callable) throws Exception {
System.out.println("-----begin-----");
System.out.println(callable.call());
System.out.println("*****end*****");
return null;
}
private static int tryThrowFinallyReturn() {
try {
throw new RuntimeException();
} finally {
return 3;
}
}
private static int tryReturnFinallyReturn() {
try {
return 1;
} finally {
return 3;
}
}
private static int tryCatchFinallyAllReturn() {
try {
return 1;
} catch (Exception e) {
return 2;
} finally {
return 3;
}
}
private static int gotoFinallyIfMeetReturnInTry() {
try {
System.out.println("try_before_return");
return 1;
} catch (Exception e) {
e.printStackTrace();
} finally {
return 3;
}
}
private static int gotoFinallyIfMeetReturnInCatch() {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("catch_before_return");
return 2;
} finally {
return 3;
}
}
private static int tryReturnFinallyNot() {
try {
return 1;
} finally {
System.out.println("finally block");
}
}
}
英文:
Assume that I hava a Method that take Callable interface as parameters.
With java reflection.I want to invoke a method that take a method
as parameter.
I got an Exception:Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
Below shows my code.
Any one knows how to archive my intent?
Appreciate for you answer!
package com.helloworld;
import android.annotation.TargetApi;
import android.os.Build;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**
* @author linjiejun
*/
public class FinallyBlock {
public static void main(String[] args) throws Exception {
// template(FinallyBlock::tryThrowFinallyReturn);
// template(FinallyBlock::tryReturnFinallyReturn);
// template(FinallyBlock::tryCatchFinallyAllReturn);
// template(FinallyBlock::gotoFinallyIfMeetReturnInTry);
// template(FinallyBlock::gotoFinallyIfMeetReturnInCatch);
Method[] methods = FinallyBlock.class.getDeclaredMethods();
Method templateMethod = FinallyBlock.class.getDeclaredMethod("template", Callable.class);
for (Method method : methods) {
if (method.getName().equals("main") || method.getName().equals("template")) {
continue;
}
System.out.println(templateMethod.invoke(null,method));
}
}
@TargetApi(Build.VERSION_CODES.O)
private static <T> T template(Callable<T> callable) throws Exception {
System.out.println("-----begin-----");
System.out.println(callable.call());
System.out.println("*****end*****");
return null;
}
// private static int tryThrowEx() {
//
// }
//region finally 中有return 语句,try,catch block中的return,以及抛出异常都将失效。
//
// try 中抛出的异常,对catch依旧有效。
private static int tryThrowFinallyReturn() {
try {
throw new RuntimeException();
} finally {
return 3;
}
}
private static int tryReturnFinallyReturn() {
try {
return 1;
} finally {
return 3;
}
}
private static int tryCatchFinallyAllReturn() {
try {
return 1;
} catch (Exception e) {
return 2;
} finally {
return 3;
}
}
//endregion
/**
* try 中没有遇到return语句的内容会执行
* try 中遇到return语句,
* 就将控制权转移给
* finally block
*
* @return
*/
private static int gotoFinallyIfMeetReturnInTry() {
try {
System.out.println("try_before_return");
return 1;
} catch (Exception e) {
e.printStackTrace();
} finally {
return 3;
}
}
/**
* catch block 同 try block
* catch block 中没有遇到return语句的内容会执行
* 遇到return语句
* 就将控制权转移给
* finally block
*
* @return
*/
private static int gotoFinallyIfMeetReturnInCatch() {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("catch_before_return");
return 2;
} finally {
return 3;
}
}
private static int tryReturnFinallyNot() {
try {
return 1;
} finally {
System.out.println("finally block");
}
}
}
答案1
得分: 1
你的 template()
方法接受一个 Callable<T>
,但你传递了一个 Method
,它没有实现 Callable<T>
,所以出现了错误。你需要实现 Callable 接口。
所以,作为建议,你可以像这样做:
1- 创建一个 Callable 类(如果你想的话,可以使用匿名类)
public class MyCallableMethod implements Callable<Integer> {
private Method m;
public MyCallableMethod(Method m){
this.m=m;
}
@Override
public Integer call() throws Exception {
return this.m.invoke(null);
}
}
2- 将
System.out.println(templateMethod.invoke(null, method));
改为
System.out.println(templateMethod.invoke(null, new MyCallableMethod(method)));
当然,这只是与 "理论" 代码一起工作的示例,因为我无法编写、编译或调试代码。
另一种解决方法可能是将 template() 的签名从
private static <T> T template(Callable<T> callable)
改为
private static <T> T template(Method callable)
然后相应地更改方法体,但我相信你需要 callable 来执行某种类型的并发任务。
英文:
Your template()
method accepts a Callable<T>
, instead you pass it a Method
which does not implement Callable<T>
, thats why the error. You need to implement the Callable Interface.
So, just as suggestion you could do something like this
1- create a Callable Class (you can do an anonomus class if you want)
public class MyCallableMethod implements Callable<Integer> {
private Method m;
public MyCallableMethod(Method m){
this.m=m;
}
@Override
public Integer call() throws Exception {
return this.m.invoke(null);
}
}
2 change
System.out.println(templateMethod.invoke(null,method));
whith
System.out.println(templateMethod.invoke(null,new MyCallableMethod(method)));
Of course this is just a trace of work with "theoric" code, as i cant neither write, neither compile nor debug the code.
Another solution could be change the signature of template() from
private static <T> T template(Callable<T> callable)
to
private static <T> T template(Method callable)
and change the method body accordingly, but i believe you need callable for some type of concurrent task
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论