无界通配符<?>很容易和原生类型混淆。

以List为例:

List表示持有任何Object类型的原生List,其实就等价于List<Object>

List<?>表示某种具有特定类型的非原生List(同构集合),只是我们不知道它的具体类型是什么,所以我们就不允许往里set数据

看下面例子:

 public class Wildcards {

     // 这里Holder等价于Holder<Object>,Holder<Object>没警告但下面的方法调用时除第一个都会报ERROR,Holder会有警告
static void saveData(Holder holder, Object arg) {
holder.set(arg); // [Warning] Type safety: The method set(Object) belongs to the raw type Holder. References to generic type Holder<T> should be parameterized
Object obj = holder.get();
System.out.println(obj.getClass().getSimpleName() + ": " + obj.toString());
} // 因为不知道Holder<?>的具体类型是什么,所以我们就不允许往里set数据
static void saveDataError(Holder<?> holder, Object arg) {
// holder.set(arg); // [Compile Error] The method set(capture#1-of ?) in the type Holder<capture#1-of ?> is not applicable for the arguments (Object)
// holder.set(new Wildcards()); // Same Compile Error
Object obj = holder.get();
System.out.println(obj.getClass().getSimpleName() + ": " + obj.toString());
} public static void main(String[] args) {
Holder h1 = new Holder<Long>();
Holder<Long> h2 = new Holder<Long>();
Holder<?> h3 = new Holder<Long>();
Holder<? extends Long> h4 = new Holder<Long>(); saveData(h1, 1L); // Long: 1
saveData(h2, 2L); // Long: 2
saveData(h3, 3L); // Long: 3
saveData(h4, 4L); // Long: 4 saveDataError(h1, 5L); // Long: 1
saveDataError(h2, 6L); // Long: 2
saveDataError(h3, 7L); // Long: 3
saveDataError(h4, 8L); // Long: 4
}
} class Holder<T> {
private T value;
public Holder() { }
public Holder(T val) { value = val; }
public void set(T val) { value = val; }
public T get() { return value; }
@Override public boolean equals(Object obj) { return value.equals(obj); }
}

捕获转换技术

如果向一个使用<?>的方法传递原生类型,那么对于编辑器来说,可能会推断出实际的类型参数,使得这个方法可以调用另一个使用确切类型的的方法。下面是一个例子:

 public class CaptureConversion {

     static <T> void getData(Holder<T> holder) {
T t = holder.get();
System.out.println(t.getClass().getSimpleName() + ": " + t);
} static void chapterGet(Holder<?> holder) {
getData(holder);
} public static void main(String[] args) {
Holder h1 = new Holder<Long>(1L);
chapterGet(h1); // Long: 1
}
}

Java泛型(7):无界通配符<?>的更多相关文章

  1. Java泛型解析(02):通配符限定

    Java泛型解析(02):通配符限定      考虑一个这种场景.计算数组中的最大元素. [code01] public class ArrayUtil { public static <T&g ...

  2. JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)

    一.通配符上限和通配符下限接受的类型 通配符上限:<? extends T> 通配符下限:<? super T> 以下代码是测试结果,注释为解释说明 package xayd. ...

  3. Java泛型之上、下界通配符的理解(适合初学)

    泛型的由来 为什么需要泛型   Java的数据类型一般都是在定义时就需要确定,这种强制的好处就是类型安全,不会出现像弄一个ClassCastException的数据给jvm,数据安全那么执行的clas ...

  4. 什么情况下不能使用 Java 泛型

    1. 前言 Java 1.5 引入了泛型来保证类型安全,防止在运行时发生类型转换异常,让类型参数化,提高了代码的可读性和重用率.但是有些情况下泛型也是不允许使用的,今天就总结一下编码中不能使用泛型的一 ...

  5. Java 泛型和通配符解惑

    转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T  有类型 ?  未知类型 一.通配符的上界 既然知道List<Cat>并不是Lis ...

  6. Java 泛型 通配符类型

    Java 泛型 通配符类型 @author ixenos 摘要:限定通配符类型.无限定通配符类型.与普通泛型区别.通配符捕获 通配符类型 通配符的子类型限定(?都是儿孙) <? extends ...

  7. java泛型通配符?

    转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T  有类型 ?  未知类型 一.通配符的上界 既然知道List<Cat>并不是Lis ...

  8. JAVA 泛型中的通配符 T,E,K,V,?

    前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据 ...

  9. 【转】聊一聊-JAVA 泛型中的通配符 T,E,K,V,?

    原文:https://juejin.im/post/5d5789d26fb9a06ad0056bd9 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型 ...

随机推荐

  1. wiki页面文本挖掘

    import os,sysimport sysfrom bs4 import BeautifulSoupimport urllib.request# reload(sys)# sys.setdefau ...

  2. 低级键盘钩子,在WIN7以上版本的问题

    最近在项目用到低级键盘钩子.发现一个很奇怪的事情,在开发环境和测试环境下都正常运行的键盘钩子, 到了现场环境,总是偶发性出现 键盘钩子不能用了,而且退出时产生1404 错误. 后经过阅读MSDN 的R ...

  3. OEL7.2下Oracle11.2.0.4RAC部署

    OEL7.2下Oracle11.2.0.4RAC部署 一. 安装步骤简述 u OEL7.2操作系统安装 u RAC 安装环境配置 u ORACLE CRS安装 u ORACLE DB软件安装 u OR ...

  4. 题解 [BZOJ1925][SDOI2010] 地精部落

    题面 解析 这个似乎并不好讲啊 设\(f[i][j]\)表示有\(i\)座山, 最后一座山到达高度是\(i\)座中第\(j\)大的, 且最后一座山是山谷. 注意,\(i\)是代表有\(i\)座山,并不 ...

  5. 外观模式(Facade)---结构型模式

    1 基础知识 定义:提供了一个统一的接口(外观类),用来访问子系统中的一群接口.特征:定义了一个高层接口让子系统更容易使用,减少了外部与子系统内多个模块的耦合. 本质:封装交互,简化调用. 优点:简化 ...

  6. [Luogu] 计数

    https://www.luogu.org/problemnew/show/P3130 #include <cstdio> #include <iostream> using ...

  7. 转:JMeter5的If Controller操作解析

    问题描述 在JMeter中添加了If Controller控制器,然后再控制器的表达式输入框中输入了预先构造的为“真”条件,执行Run发现结果树中并没有监控到执行的记录. 问题分析 在最新版JMete ...

  8. 在浏览器上打开、预览Excel xlsx表格文件

    现在的HTML5,有了FileReader文件读写API, 真是让javascript的能力大幅提升. 解析zip压缩文件.解析Excel xlsx 表格文档各种文件预览,实现起来也有了可能性,以前的 ...

  9. skbuff

    在2.6.24之后这个结构体有了较大的变化,此处先说一说2.6.16版本的sk_buff,以及解释一些问题. 一. 先直观的看一下这个结构体~~~~~~~~~~~~~~~~~~~~~~在下面解释每个字 ...

  10. lavarel数据库查找别名操作

    lavarel数据库查找别名操作 一.总结 一句话总结: 当有表前缀的时候:DB::table('users as table1')->select(DB::raw('table1.id'))- ...