How to work with varargs and reflection

半世苍凉 提交于 2019-11-26 18:55:43
Test.class.getDeclaredMethod("foo", String[].class);

works. The problem is that getMethod(..) only searches the public methods. From the javadoc:

Returns a Method object that reflects the specified public member method of the class or interface represented by this Class object.

Update: After successfully getting the method, you can invoke it using:

m.invoke(this, new Object[] {new String[] {"a", "s", "d"}});

that is - create a new Object array with one element - the String array. With your variable names it would look like:

m.invoke(this, new Object[] {a});

//prior to edit:

Your problem is the fact that getMethod looks for a public member.

From the Class.getMethod (emphasis mine):

Returns a Method object that reflects the specified public member method of the class or interface represented by this Class object

So you have two options:

  • Make public void foo(String... s) and use getMethod
  • Use getDeclaredMethod instead

Note that the same difference exists for getField/s vs getDeclaredField/s and getConstructor/s vs getDeclaredConstructor/s.


//invoke problem

This is particularly nasty, but what happens is that invoke(Object obj, Object... args) makes it tricky if you need to pass an array of reference type as an only argument, because it is cast-able to Object[], even though it should be wrapped inside a new Object[1] instead.

You can do:

m.invoke(this, new Object[] {a}); // Bohzo's solution

This bypasses the vararg mechanism. More succinctly you can also do:

m.invoke(this, (Object) a);

The cast to Object makes the vararg mechanism do the work of creating the array for you.

The trick is also needed when passing a null as an argument to varargs, and has nothing to do with reflection.

public void foo(String... ss) {
    System.out.println(ss[0]);
}

    foo(null); // causes NullPointerException
    foo((String) null); // prints "null"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!