Java - How to create a Class>> object

2019-08-14 20:25发布

问题:

I'm sorry if this is a noob question. I have a method which takes a Class object with the generic type as a parameter. I am able to do the following:

Class cs = Map.class;

but when I pass this I get an "NoSuchMethodException" since the method is declared:

public void doSomething(Class<Map<Object, List<Object>>> theclass){
...     
}

I have tried to cast it like this:

Class cs = (Class<Map<Object, List<Object>>>)(Class<?>)Map.class;

but I still get the same exception.

Is there a way to do this?

I cannot post the full code here but I have reproduced the error: The application is actually using reflection. I can not post the original code here but I have reproduced the exception:

import java.lang.reflect.Method;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Class c = null;
        try {
            c = Class.forName("Second");
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        }
        String m = "doSomething";
        Method method = null;
        Class cs = Map.class;
        try{
            method = c.getMethod(m, cs);
        } catch (NoSuchMethodException e){
            e.printStackTrace();
        }
    }
}

class Second{
    public static void doSomething(Class<Map<Object, List<Object>>> theclass){
        System.out.println("HERE I AM!");   
    }   
}

The exception:

java.lang.NoSuchMethodException: Second.doSomething(java.util.Map)
    at java.lang.Class.throwNoSuchMethodException(Class.java:283)
    at java.lang.Class.getMethod(Class.java:825)
    at Main.main(Main.java:16)

回答1:

If you're doing such casting, I think you're fighting against the type system that's designed to help you. For starters,

Class cs = Map.class;

is a raw type (see here for more info). Have you tried instantiating a class of your required Map type, and passing the class of that to your function ?

e.g.

(new HashMap<Object, List<Object>>()).getClass();

Note: as ruakh as noted in the comments above, you'd have to pass an instance of the Map interface, and as such that method declaration above would prohibit this. Basically there's a fundamental API design issue here!



回答2:

Got it! I have changed the following line:

method = c.getMethod(m, cs);

to:

method = c.getMethod(m, cs.getClass());

Now it works!