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

以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. mybatis的配置文件详解(二)

    一.properties 这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递.例如 1) <?xml versio ...

  2. adreno的tbdr

    看完apple的(&&powervr) 再来撸高通的.. FlexRender 能自己选三种模式 Direct Binning 这个只是分块 HWVizBinning 这个估计就是tb ...

  3. UUID值

    生成这种值:b28043c8-fdb7-4c9e-8df5-b869d38f829d

  4. 单例模式(Singleton)---创建型

    1 单例模式的使用场景 (1)当创建一个对象所占用的资源很多,但同时又需要使用到该对象 (2)当堆系统内的资源要求统一读写时,比如读写的配置信息,此时必须要求创建的实例信息相同 (3)当有多个实例可能 ...

  5. Python GUI编程(Tkinter)(一)

    tk官网的教程学习: https://tkdocs.com/tutorial/firstexample.html 学习blog: https://www.cnblogs.com/aland-1415/ ...

  6. boost 函数与回调

    result_of 含义:result_of可以帮助程序员确定一个调用表达式的返回类型,主要用于泛型编程和其他boost库组件,它已经被纳入TR1 头文件:<boost/utility/resu ...

  7. IntelliJ 如何显示代码的代码 docs

    希望能够在 IntelliJ 代码上面显示方法的 docs. 如何进行显示? 你可以使用 Ctrl + Q 这个快捷键来查看方法的 Docs. https://blog.ossez.com/archi ...

  8. Jmeter(十四)取样器之JDBC Request

    在接口测试中,需要与数据库进行交互,这时候需要用到JDBC Request取样器. JDBC Request可以向数据库发送一个请求(sql语句),一般它需要配合JDBC Connection Con ...

  9. Linux环境下Gitblit服务搭建及秘钥配置

    一.安装gitblit服务 1.下载地址 https://pan.baidu.com/s/1wQ3TEE_gw5xZvyFPZB9xFg 2.上传至linux服务器并解压缩 tar xvf gitbl ...

  10. 【洛谷1361】 小M的作物(最小割)

    传送门 洛谷 Solution 这是一个比较实用的套路,很多题目都有用,而且这个套路难以口胡出来. 考虑把每一个附加贡献重新建一个点,然后向必需的点连边,流量为val. 然后直接种植的从源点向这个点连 ...