Pet*_*Mmm 24 java reflection variadic-functions
简单的问题,如何使这段代码工作?
public class T {
public static void main(String[] args) throws Exception {
new T().m();
}
public // as mentioned by Bozho
void foo(String... s) {
System.err.println(s[0]);
}
void m() throws Exception {
String[] a = new String[]{"hello", "kitty"};
System.err.println(a.getClass());
Method m = getClass().getMethod("foo", a.getClass());
m.invoke(this, (Object[]) a);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
class [Ljava.lang.String;
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Run Code Online (Sandbox Code Playgroud)
Boz*_*zho 47
Test.class.getDeclaredMethod("foo", String[].class);
Run Code Online (Sandbox Code Playgroud)
作品.问题是getMethod(..)只搜索public方法.来自javadoc:
返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定公共成员方法.
更新:成功获取方法后,您可以使用以下方法调用它:
m.invoke(this, new Object[] {new String[] {"a", "s", "d"}});
Run Code Online (Sandbox Code Playgroud)
那就是 - Object用一个元素创建一个新数组 - String数组.使用您的变量名称,它看起来像:
m.invoke(this, new Object[] {a});
Run Code Online (Sandbox Code Playgroud)
pol*_*nts 10
//在编辑之前:
你的问题是getMethod寻找public成员的事实.
来自Class.getMethod(强调我的):
返回一个
Method对象,该对象反映此Class对象所表示的类或接口的指定公共成员方法
所以你有两个选择:
public void foo(String... s)和使用getMethodgetDeclaredMethod改用请注意,getField/svs getDeclaredField/s和getConstructor/svs 存在相同的差异getDeclaredConstructor/s.
// invoke问题
这尤其令人讨厌,但是invoke(Object obj, Object... args)如果你需要传递一个引用类型的数组作为唯一的参数,那么会发生什么变得棘手,因为它是可以转换的Object[],即使它应该被包含在内部new Object[1].
你可以做:
m.invoke(this, new Object[] {a}); // Bohzo's solution
Run Code Online (Sandbox Code Playgroud)
这绕过了vararg机制.你可以更简洁地做到:
m.invoke(this, (Object) a);
Run Code Online (Sandbox Code Playgroud)
Object强制转换使vararg机制能够为您创建数组.
将a null作为参数传递给varargs 时也需要这个技巧,而且与反射无关.
public void foo(String... ss) {
System.out.println(ss[0]);
}
foo(null); // causes NullPointerException
foo((String) null); // prints "null"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17124 次 |
| 最近记录: |