我有一个像这样的java界面
public interface MyInterface<T> {
public <V extends T> V get(String key, Bundle bundle);
}
Run Code Online (Sandbox Code Playgroud)
请注意方法的<V extends T>
类型参数.
然后我上课了 MyFoo implements MyInterface
class MyFoo implements MyInterface<Object> { // Object because can be any type
@Override public <V> V get(String key, Bundle bundle) {
return new Other();
}
}
Run Code Online (Sandbox Code Playgroud)
所以,当我现在有这样一个类:
class Bar {
public Other other;
public Other setOther(Other other);
}
Run Code Online (Sandbox Code Playgroud)
然后我想在一个实例中MyFoo
设置:Other
Bar
MyFoo foo = new MyFoo();
Bar bar = new Bar();
bar.other = foo.get();
Run Code Online (Sandbox Code Playgroud)
这非常有效.类型可以由java泛型确定.不需要额外的演员阵容.
但是,如果我想使用bar.setOther()
那么无法确定类型:
MyFoo foo = new MyFoo();
Bar bar = new Bar();
bar.setOther(foo.get()); // Fails
Run Code Online (Sandbox Code Playgroud)
然后我得到以下编译错误:
错误:不兼容的类型:对象无法转换为其他
我不明白为什么这对该bar.setOther( foo.get() )
方法不起作用,但在直接访问该字段时起作用bar.other = foo.get()
任何想法如何解决,而无需添加额外的演员 bar.setOther( (Other) foo.get() )
在赋值中,Java 编译器通过查看要赋值的类型来知道该方法使用什么返回类型。所以回答你的问题
\n\n\n\n\n知道如何在不添加像\n 这样的额外演员的情况下解决这个问题吗
\nbar.setOther( (Other) foo.get() )
?
您可以通过以下方式做到这一点:
\n\nOther value = foo.get();\nbar.setOther(value);\n
Run Code Online (Sandbox Code Playgroud)\n\n还有另一种方法,看起来更糟糕,但仍然没有演员:
\n\nbar.setOther(foo.<Other>get());\n
Run Code Online (Sandbox Code Playgroud)\n\n第三种选择:切换到 Java 8;在 Java 8 中你可以这样做bar.setOther(foo.get());
。
对于 Java 7,这种类型推断的规则在JLS 第 15.12.2.8 节中指定:
\n\n\n\n\n如果任何方法的类型参数不是从实际参数的类型推断出来的,那么现在将按如下方式推断它们。
\n\n如果方法结果出现在将进行 赋值转换 (\xc2\xa75.2) 到类型 S 的上下文中,则 [...]
\n
如果在赋值表达式中使用方法结果,则该方法结果需要进行赋值转换。
\n\n\n\n\n\n
\n- 否则,在假设方法结果已分配给类型变量的情况下,通过调用本节中描述的\n 过程来推断未解析的类型参数
\nObject
。
如果在方法中使用未解析的类型参数,而该方法的结果未在赋值表达式中使用,则该类型参数将被解释为将该方法结果分配给类型为 的变量Object
。因此,这意味着在这种情况下,如果该get()
方法的结果未分配给变量,则该get()
方法的返回类型将被视为Object
。
归档时间: |
|
查看次数: |
156 次 |
最近记录: |