简体   繁体   中英

How to use generic in Class.class

I want to avoid the warning:

"type safety the expression of type needs unchecked conversion to conform to Class"

From this sentence:

Class<MyInterface> cc = interpreter.get("Myclass", Class.class );

I have tried:

Class<MyInterface> cc = interpreter.get("Myclass", Class<MyInterface>.class );

But is invalid.

How can I do that without @SuppressWarnings("unchecked")

The signature of interpreter.get:

T interpreter.get(String name, Class<T> javaClass)

The context: I use the library Jython and I define a class in Python who implement MyInterface, then I capture this class in Java then I create instances of them. That is why I need the class itself, not a instance of the class.

The code is something like:

PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("from cl.doman.python import MyInterface");
....
interpreter.exec(pythonCode);
Class<MyInterface> cc = interpreter.get("Myclass", Class.class);
MyInterface a = (MyInterface) cc.newInstance();

My code work fine But I can't suppress the warning.

Probably

Class<?> clazz = interpreter.get("Myclass", Class.class); 
Class<? extends MyInterface> cc = clazz.asSubclass(MyInterface.class);
// look, Ma, no typecast!
MyInterface a = cc.newInstance();

Update Given the new context of the question (the use of PythonInterpreter), the contents of my answer would be for a generic T get(String name, Class<T> javaClass) and not for use with the PythonInterpreter.

I wrote a small example along with a simple "Interpreter" class that defines a simple method per your example. Given your example get method. I would expect it to return T and not Class<T> .

The below example also reminds me of a (very simple) example of Spring Bean loading where you may load a concrete implementation and return the interface.

public class Test {

    public static void main(String[] args) {
        final Interperter<MyInterface> interperter = new Interperter<MyInterface>() ;
        final MyInterface i = interperter.get("MyClass", MyInterface.class);
        System.out.println(i);
    }

    public static class Interperter<T> {
        // A sample get method with the same signature, The body's contents shouldn't matter to much for this demonstration.
        public T get(String name, Class<T> javaClass) {
            try {
                final Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(name);
                return (T) clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                e.printStackTrace();
                return null;
            }
        }
    }

}

A sample Interface

public interface MyInterface {}

A sample Base Class

public final class MyClass implements MyInterface {

    @Override
    public String toString() {
        return "MyClass{}";
    }
}

The programs output: MyClass{}

Let me know if you feel that I misunderstood your question :)

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