java - 使用无界通配符会捕获错误但仅在使用原始类型时才会被标记为警告的情况
问题描述
以下是Maurice Naftalin 和 Philip Wadlerunbounded wildcard types
对 vsraw types
之间比较的引用。Java generics and collection
我们建议使用无界通配符类型而不是原始类型,因为它们提供了更强的静态类型保证;当您使用无界通配符时,许多被捕获为错误的错误只会在您使用原始类型时被标记为警告。
但是本书没有提供代码示例来解释这种情况。我想知道是否有人可以通过提供代码示例来添加解释?
解决方案
好吧,你可以改编同一章的一些例子来重现这种情况。
例如,考虑以下泛型类:
class Node<E> {
private E value;
@Override public String toString(){ return value.toString(); }
}
现在,假设您编写了以下代码,这是错误的:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node) {
Node other = (Node) o;
other.value = node.value; //Uh oh! Warning
}
System.out.println(node); //Hello
System.out.println(other); //Hello - WTH!
如果你尝试编译它,你只会得到一个警告,但它仍然可以编译得很好:
javac -Xlint:unchecked Node.java
Node.java:21: warning: [unchecked] unchecked assignment to variable value as member of raw type Node
other.value = node.value;
^
1 warning
但是,如果您更改代码以使用无界通配符:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node<?>) {
Node<?> other = (Node<?>) o;
other.value = node.value; //Uh oh! Compiler error
}
现在编译时会出现以下错误:
javac -Xlint:unchecked Node.java
Node.java:21: error: incompatible types: String cannot be converted to CAP#1
other.value = node.value;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
1 error
因此,正如您所见,无界通配符提供了比原始类型更好的类型检查保证。
推荐阅读
- python - 如何忽略文件中以“##”开头的行并在 csv 模块中加载表?
- c# - 如何使用 docfx 生成带有参考的文档
- php - 注册 Laravel 后创建重定向
- javascript - 在登录页面上反应受保护的路由问题而没有注销重定向
- google-app-engine - App Engine:“gcp-build”是否每个版本或每个实例运行一次?
- java - JPQL 查询不适用于不区分大小写的参数
- yocto - Yocto - 我的图像中不存在文件(但存在于构建环境中的 tmp/work 目录中)
- ios - Android 可穿戴设备可以与 iOS 一起使用,通过 BLE 连接吗?有没有可用的SDK?
- go - 为什么 Logrus 将日志写入 Linux 日志?
- r - 如何识别R中自变量的组合冗余