简体   繁体   中英

Why reflection doesn't find method?

public class Test1<Type>
{
    public Type getCompositeMessage(Type... strings)
    {
        Type val = (Type) "";

        for (Type str : strings) {
            val = (Type) ((String)val + (String)str);
        }
        return val;
    }
}

Retrieving method:

try
{
    Class<?> c = Class.forName("test1.Test1");
    Method[] allMethods = c.getDeclaredMethods();
    for (Method m : allMethods) {
        String mname = m.getName();
        System.out.println(mname);
    }

    Method m = c.getMethod("getCompositeMessage");
    m.setAccessible(true);
    Object o = m.invoke(c, "777777777777777777777777");
    System.out.println(m);
}
catch (Exception e)
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Output:

getCompositeMessage
java.lang.NoSuchMethodException: test1.Test1.getCompositeMessage()
at java.lang.Class.getMethod(Unknown Source)
at test1.Main.main(Main.java:25)

But name of method is exactly the same! Why I receive NoSuchMethodException ? thanks.

After you fixed the misspelling, you are still looking for the wrong method:

The method is defined as:

getCompositeMessage(Type... strings)

but you are looking for

getCompositeMessage()

without parameters.

You need to use:

c.getMethod("getCompositeMessage", Object[].class);

The next problem will be the call to invoke(), you are passing the class references in stead of the object on which the method should be called.

The next bug is that you are not passing the correct arguments to the function:

 Object o = m.invoke(new Test1<String>(), new Object[] {
          new String[] {"777777777777777777777777"}});

And the next problem is that you want output the result of the method instead of the method-object in the following line:

System.out.println(o);

You can find it using

Test1.class.getDeclaredMethod("getCompositeMessage", Type[].class);

(that would be true if Type were a class or interface, since it's a generic parameter you are looking for this:)

Test1.class.getDeclaredMethod("getCompositeMessage", (Object) Object[].class);

And the error you are getting results from the fact that the first parameter needs to be an instance, not the class Object.

wrong:

Object o = m.invoke(c /* c is a class Object, but it must be an instance */,
                    "777777777777777777777777" /* this must be an array */);

right:

Type1<String> t = new Type1<String>();
Object o = m.invoke(t, new Object[]{"foo", "bar"};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM