阅读Java在线教程我对通配符捕获一无所知.例如:
import java.util.List;
public class WildcardError {
void foo(List<?> i) {
i.set(0, i.get(0));
}
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器不能保持赋值安全?它知道,通过执行例如带有整数列表的方法,它从i.get得到一个Integer值.因此,它尝试将索引0处的Integer值设置为相同的整数列表(i).那么,出了什么问题?为什么要写Wildcard助手呢?
mer*_*ike 22
为什么编译器不能保持赋值安全?它知道,通过执行例如带有整数列表的方法,它从i.get得到一个Integer值.因此,它尝试将索引0处的Integer值设置为相同的整数列表(i).
换句话说,为什么编译器不知道通配符的两种用法类型List<?>中
i.set(0, i.get(0));
Run Code Online (Sandbox Code Playgroud)
是指相同的实际类型?
那么,这将要求编译器知道i包含表达式的两个评估的相同实例.由于i甚至不是最终的,编译器必须检查是否i可能在评估两个表达式之间分配.这样的分析只对局部变量很简单(谁知道被调用的方法是否会更新特定对象的特定字段?).这在编译器中非常复杂,因为它很少显示出好处.我想这就是为什么Java编程语言的设计者通过指定相同通配符类型的不同用法具有不同的捕获来使事情变得简单.
Mat*_*all 20
为什么编译器不能保持赋值安全?
编译器不知道任何关于类型中的元素List<?> i通过定义?.通配符并不会意味着"任何类型;" 它意味着"某种未知类型".
它知道,通过执行例如带有整数列表的方法,它从i.get得到一个Integer值.
这是真的,但正如我上面所说:编译器只能知道 - 在编译时,记住 - i.get(0)返回一个Object,这是...的上限?.但是,没有任何保证,?是在运行时 Object,所以没有办法让编译器知道i.set(0, i.get(0))是安全的呼叫.这就像写这个:
List<Foo> fooz = /* init */;
Object foo = fooz.get(0);
fooz.set(0, foo); // won't compile because foo is an object, not a Foo
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6126 次 |
| 最近记录: |