Ben*_*ler 4 java generics java-7
我想让一个函数返回一个保证实现两个接口的对象。在编译时不一定知道确切的对象。我的代码看起来像:
class HelloWorld {
public interface A {}
public interface B {}
public static class C implements A, B {}
public static class D implements A, B {}
public static <T extends A & B> void g(T t) {}
public static <T extends A & B> T f(boolean b) {
if (b)
return new C(); // Doesn't compile
return new D(); // Doesn't compile
}
public static void main(String []args){
g(f(true));
g(f(false));
<what_should_I_write_here> x = f(<user_inputted_boolean>);
}
}
Run Code Online (Sandbox Code Playgroud)
尝试编译时出现以下错误:
HelloWorld.java:13: 错误:类型不兼容:C 无法转换为 T
return new C();
^
其中 T 是类型变量:
T extends A,B 在方法 f(boolean)
HelloWorld.java:14 中声明:错误:不兼容的类型:D 无法转换为 T
return new D();
^
其中 T 是类型变量:
T extends A,B 在方法 f(boolean) 中声明
这不起作用,因为您不能从函数返回两种不同的类型,并且C
和D
是不同的类型。
有没有办法让上面的代码编译?
您对类型变量有根本的误解。当你声明一个方法时
public static <T extends A & B> T f(boolean b) { … }
Run Code Online (Sandbox Code Playgroud)
您声明了一个类型变量 T
,调用者可以为其分配实际类型(或调用者上下文的类型变量)。例如,调用者可以执行以下操作:
class SomethingCompletelyUnknownToF implements A,B {}
SomethingCompletelyUnknownToF var = f(trueOrFalse);
Run Code Online (Sandbox Code Playgroud)
编译器会接受,因为调用者SomethingCompletelyUnknownToF
使用的类型满足类型必须实现的约束or 。当然,这将在运行时失败,因为既不能也不能分配给. 事实上,它不可能满足返回它甚至不知道的特定类型的期望。T
f
A
B
C
D
SomethingCompletelyUnknownToF
f
总而言之,类型变量不是方法可以分配类型的变量,类型变量是调用者选择的类型的占位符。
所以方法签名
public static <T extends A & B> void g(T t) { … }
Run Code Online (Sandbox Code Playgroud)
更有意义的是,无论调用者选择的实际类型如何T
,它将满足方法的实现期望,A
并且B
在作为参数传递时。当然,g
不能指望它是,D
或者C
,因为它可能是一个完全未知的类型,实现了A
和B
。
也就是说,在 Java 中没有办法表示返回类型扩展了两种类型(除了声明扩展这两种类型的具体类型)。在的情况下RandomAccess
,无论如何都不需要打扰,因为它没有任何后果。请注意,JRE 类也永远不会声明返回的何时List
保证实现此标记接口。这是通过从不期望它作为参数类型来适应的。同样,Serializable
永远不会在任何地方声明为返回或参数类型。
归档时间: |
|
查看次数: |
1143 次 |
最近记录: |