【发布时间】:2020-11-28 20:03:45
【问题描述】:
我想创建一个方法来接受任何实现任何接口I 的类T。
然后对类做点什么,返回实现的接口I。
这是我尝试过的:
class MyLibrary {
public static <I, T extends I> I registerImplementation(Class<T> classImpl) {
I interfaceImpl = (I) classImpl.newInstance();
return interfaceImpl;
}
}
然后我将创建一个接口和一个实现该接口的类:
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");
}
}
但是,当我调用引用UserClass的方法时,它返回相同的类类型T而不是接口类型I,从而允许调用所有未在接口中声明的类方法.
即在下面的语句中,即使 registerImplementation() 被声明为返回对 UserInterface 的引用,编译器仍将引用视为指向 UserClass_v1_10_R2 的实例,从而允许访问不在接口中的实现方法。
MyLibrary.registerImplementation(UserClass_v1_10_R2.class).doVersionSpecificStuff();
将其与假定的相同进行对比
UserInterface uiObj = MyLibrary.registerImplementation(UserClass_v1_10_R2.class);
uiObj.doVersionSpecificStuff(); // This does not compile
【问题讨论】:
-
如果你明确指定泛型类型参数会发生什么:
MyLibrary.<UserInterface, UserClass_v1_10_R2>registerImplementation(UserClass_v1_10_R2.class).doVersionSpecificStuff(); -
可以
UserClass_v1_10_R2 r = MyLibrary.registerImplementation(UserClass_v1_10_R2.class);吗? -
@JacobG。编译错误,无法解析符号“registerImplementation”
-
@daniu 这是因为这个函数的返回值是UserClass,但是我需要返回它实现的接口而不具体声明哪个接口,因为它的名字是由用户提供的。
-
@user7401478 “无法解析符号”听起来像是 Intellij 特有的错误 - 你能直接用
javac编译建议的代码,看看是否能解决问题吗?