此代码无法编译。我想知道我做错了什么:
private static Importable getRightInstance(String s) throws Exception {
Class<Importable> c = Class.forName(s);
Importable i = c.newInstance();
return i;
}
其中Importable是接口,字符串s是实现类的名称。 编译器说:
./Importer.java:33: incompatible types
found : java.lang.Class<capture#964 of ?>
required: java.lang.Class<Importable>
Class<Importable> c = Class.forName(format(s));
感谢您的帮助!
所有解决方案
Class<? extends Importable> c = Class.forName(s).asSubclass(Importable.class);
和
Class<? extends Importable> c = (Class<? extends Importable>) Class.forName(s);
和
Class<?> c = Class.forName(format(s));
Importable i = (Importable)c.newInstance();
给出这个错误(我不明白):
Exception in thread "main" java.lang.IncompatibleClassChangeError: class C1
has interface Importable as super class
其中C1实际上是实现可导入的(因此它理论上可以转换为可导入的)。
答案 0 :(得分:32)
使用运行时转换:
Class <? extends Importable> c
= Class.forName (s).asSubclass (Importable.class);
如果s
指定了一个没有实现接口的类,那么在运行时会出现异常。
答案 1 :(得分:7)
尝试:
Class<? extends Importable> klaz = Class.forName(s).asSubclass(Importable.class);
以下是一些说明问题的片段:
Class<CharSequence> klazz = String.class; // doesn't compile!
// "Type mismatch: cannot convert from Class<String> to Class<CharSequence>"
然而:
Class<? extends CharSequence> klazz = String.class; // compiles fine!
因此,对于interface
,您肯定需要上限通配符。 asSubclass
与doublep建议一致。
<U> Class<? extends U> asSubclass(Class<U> clazz)
Class
对象以表示由指定类对象表示的类的子类。检查强制转换是否有效,如果不是,则抛出ClassCastException
。如果此方法成功,则它始终返回对此类对象的引用。答案 2 :(得分:2)
这样的事情可能会起到作用:
Class<?> c1 = Class.forName(s);
Class<? extends Importable> c = c1.asSubclass(Importable.class);
return c.newInstance();
如果传入错误的内容,请注意ClassCastException
或NoClassDefFound
。正如@polygenelubricants所说,如果你能找到一些避免Class.forName
的方法,那就更好了!
答案 3 :(得分:0)
问题是Class.forName是一个静态方法,具有以下定义
public static Class forName(String className)抛出ClassNotFoundException
因此它根本不是绑定参数类型,编译器肯定会抛出强制转换警告,因为它无法保证类的字符串名称总能为您提供接口的实现。
如果您确定传递给方法的字符串名称是接口的实现,则可以使用SuppressWarnings注释。但我不认为使用forName和泛型的任何其他更干净的方式
答案 4 :(得分:0)
其中Importable是一个接口,字符串s是实现类的名称。
编译器无法知道,因此错误。
使用演员。与类对象本身相比,构建对象(因为这是一个经过检查的强制转换)更容易。
Class<?> c = Class.forName(s);
Importable i = (Importable) c.newInstance();
return i;