不知道如何完成这项工作:
//Have a tiny CustomServiceLoader implementation
public class MyServiceLoader {
static private Map<Class<?>, Class<?>> CONTENTS = new HashMap<>();
static public <S, T extends S> void registerClassForInterface(Class<T> c, Class<S> i) {
if (c == null) {
CONTENTS.remove(i);
} else {
CONTENTS.put(c, i);
}
}
static public <S, T extends S> Class<T> getClassForInterface(Class<S> i) {
return (Class<T>)CONTENTS.get(i);
}
}
用法:
// classes registration works perfect event check for interface conformance (e.g. T extends S really works here!):
MyServiceLoader.registerClassForInterface(Model.class, APIAsyncLoaderTask.class);
// but I can't figure out how to instantiate a class returned from my service loader:
Class c = GiftdServiceLoader.getClassForInterface(APIAsyncLoaderTask.class);
mLoaderTask = c.newInstance(); // 'new c();' also couldn't work
编译器错误:
对于该方法我还有一个奇怪的提示
public final Class<T> extends Object implements Serializable, AnnotatedElement, GenericDeclaration, Type
但我在那里看不到我的界面。使用两者时我得到相同的结果:抽象类+类和接口(interface)+类
如何使其正常工作?我想知道至少有可能吗?
最佳答案
您正在使用原始类型Class
。
Class c = GiftdServiceLoader.getClassForInterface(APIAsyncLoaderTask.class);
在此类引用上调用的任何方法中的所有泛型类型和泛型类型参数都将被删除。
正确参数化
Class<APIAsyncLoaderTask> c = MyServiceLoader.getClassForInterface(APIAsyncLoaderTask.class);
请注意,如果您不确定将从调用 getClassForInterface
中收到的内容,则应仅使用接口(interface)类型。
例如,我可以这样做
MyServiceLoader.registerClassForInterface(NotModel.class, APIAsyncLoaderTask.class);
// but I can't figure out how to instantiate a class returned from my service loader:
Class<Model> c = MyServiceLoader.getClassForInterface(APIAsyncLoaderTask.class);
Model mLoaderTask = c.newInstance(); // 'new c();' also couldn't work
并且它将失败并出现 ClassCastException
。
泛型的功能不足以防止这种情况发生。
<小时/>我相信你应该有
CONTENTS.put(i, c);
在您的registerClassForInterface
方法中。
关于java - 无法弄清楚如何实例化从具有 <S, T extends S> 等条件的函数返回的泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30742889/