我想创建一个方法来接受T实现任何接口的任何类I。
然后对类做一些事情并返回实现的接口I。
这是我尝试过的:
class MyLibrary {
public static <I, T extends I> I registerImplementation(Class<T> classImpl) {
I interfaceImpl = (I) classImpl.newInstance();
return interfaceImpl;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建一个接口和一个实现该接口的类:
interface UserInterface {
void doSomethingDefined();
}
class UserClass_v1_10_R2 implements UserInterface {
@Override
public void doSomethingDefined() {
System.out.println("What this does is well-defined");
}
public void doVersionSpecificStuff() {
System.out.println("This is not in the interface, so don't really depend on this");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我调用方法引用时UserClass,它返回相同的类类型T而不是接口类型I,从而允许调用所有未在接口中声明的类方法。
即在下面的语句中,即使registerImplementation()声明为返回对 的引用UserInterface,编译器仍将引用视为指向 的实例UserClass_v1_10_R2,从而允许访问不在接口中的实现方法。
MyLibrary.registerImplementation(UserClass_v1_10_R2.class).doVersionSpecificStuff();
Run Code Online (Sandbox Code Playgroud)
将此与所谓的相同
UserInterface uiObj = MyLibrary.registerImplementation(UserClass_v1_10_R2.class);
uiObj.doVersionSpecificStuff(); // This does not compile
Run Code Online (Sandbox Code Playgroud)
这就是编译器推断类型的方式。如果您使用特殊(未记录)标志进行编译:
javac --debug=verboseResolution=all ...
Run Code Online (Sandbox Code Playgroud)
你会看到:
Note: Deferred instantiation of method <I,T>registerImplementation(Class<T>)
MyLibrary.registerImplementation(UserClass_v1_10_R2.class).doVersionSpecificStuff();
^
instantiated signature: (Class<UserClass_v1_10_R2>)UserClass_v1_10_R2
Run Code Online (Sandbox Code Playgroud)
查看实例化的签名:(Class<UserClass_v1_10_R2>)UserClass_v1_10_R2
因此,您需要添加另一个参数来获取接口:
public static <I, T extends I> I registerImplementation(Class<I> interfaceClass, Class<T> implClass) {
// do whatever checks you want if this is an interface or if a constructor can be called....
I interfaceImpl = null;
try {
interfaceImpl = interfaceClass.cast(implClass.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
return interfaceImpl;
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您有多个接口,这会引发问题,但这是您需要考虑的事情。