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

以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. Android Vitals各性能指标介绍

    Android vitals 简介 谷歌推荐使用Android vitals来帮助开发者提高App的稳定性和性能表现. 作为这个方案的一部分, Play Console提供了Android Vital ...

  2. 前端知识体系:JavaScript基础-原型和原型链-instanceof的底层实现原理

    instanceof的底层实现原理(参考文档) instanceof的实现实际上是调用JS的内部函数 [[HasInstance]] 来实现的,其实现原理是:只要右边变量的prototype在左边变量 ...

  3. mysqldump表损坏问题

    遇到的问题:mysqldump: Error 1194: Table 'user' is marked as crashed and should be repaired when dumping t ...

  4. springBoot+websocket集群系列知识

    WebSocket简介和spring boot集成简单消息代理 Spring Boot 集成 websocket,使用RabbitMQ做为消息代理 Spring Websocket实现向指定的用户发送 ...

  5. java.util.Stack

    import java.util.Stack; public class Test { public static void main(String[] args) { Stack stack = n ...

  6. Casual Literary Notes

    写在前面的话: 人生中总会有一些惊喜,它会给予坚守的人们以奖励,提醒着人们,生命中不光是辛劳和付出. 很多收获,最后看来,往往都是因为当初的那一点坚持. -- 雷宇<现场> 1.18 上午 ...

  7. 「BZOJ 2653」middle「主席树」「二分」

    题意 一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)从\(0\)开始标号,除法取下整.给你一个长度为\(n\)的序列\(s\) ...

  8. 【线性代数】2-3:消元与矩阵的关系(Elimination and Matrix)

    title: [线性代数]2-3:消元与矩阵的关系(Elimination and Matrix) toc: true categories: Mathematic Linear Algebra da ...

  9. Java中jdk代理和cglib代理

    代理模式 给某一个对象提供一个代理,并由代理对象控制对原对象的引用.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 在Java中代理模式从实 ...

  10. RabbitMQ 简使用案例

    第一步导入依赖 : <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-clie ...