How to work with varargs and reflection

后端 未结 2 414
野性不改
野性不改 2020-11-28 10:10

Simple question, how make this code working ?

public class T {

    public static void main(String[] args) throws Exception {
        new T().m();
    }

            


        
相关标签:
2条回答
  • 2020-11-28 10:23
    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});
    
    0 讨论(0)
  • 2020-11-28 10:24

    //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"
    
    0 讨论(0)
提交回复
热议问题