Java泛型(7):无界通配符<?>
无界通配符<?>很容易和原生类型混淆。
以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):无界通配符<?>的更多相关文章
- Java泛型解析(02):通配符限定
Java泛型解析(02):通配符限定 考虑一个这种场景.计算数组中的最大元素. [code01] public class ArrayUtil { public static <T&g ...
- JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)
一.通配符上限和通配符下限接受的类型 通配符上限:<? extends T> 通配符下限:<? super T> 以下代码是测试结果,注释为解释说明 package xayd. ...
- Java泛型之上、下界通配符的理解(适合初学)
泛型的由来 为什么需要泛型 Java的数据类型一般都是在定义时就需要确定,这种强制的好处就是类型安全,不会出现像弄一个ClassCastException的数据给jvm,数据安全那么执行的clas ...
- 什么情况下不能使用 Java 泛型
1. 前言 Java 1.5 引入了泛型来保证类型安全,防止在运行时发生类型转换异常,让类型参数化,提高了代码的可读性和重用率.但是有些情况下泛型也是不允许使用的,今天就总结一下编码中不能使用泛型的一 ...
- Java 泛型和通配符解惑
转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T 有类型 ? 未知类型 一.通配符的上界 既然知道List<Cat>并不是Lis ...
- Java 泛型 通配符类型
Java 泛型 通配符类型 @author ixenos 摘要:限定通配符类型.无限定通配符类型.与普通泛型区别.通配符捕获 通配符类型 通配符的子类型限定(?都是儿孙) <? extends ...
- java泛型通配符?
转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T 有类型 ? 未知类型 一.通配符的上界 既然知道List<Cat>并不是Lis ...
- JAVA 泛型中的通配符 T,E,K,V,?
前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据 ...
- 【转】聊一聊-JAVA 泛型中的通配符 T,E,K,V,?
原文:https://juejin.im/post/5d5789d26fb9a06ad0056bd9 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型 ...
随机推荐
- c#使用 NServiceKit.Redis 封装 RedisHelper
在说StackExchange.Redis 的时候说了,因为我们的项目一直.net4.0不升级,没有办法,我说的不算,哈哈,又查了StackExchange.Redis在.net4.0使用麻烦,所以选 ...
- IDEA-maven的配置
一.下载maven的包 http://www.apache.org/ 1.在网页中打开上面的网址,进入下面的页面 2.拖动滚动条往下拉,找到maven 进入之后,点击Download 3.选择wind ...
- python的内置函数(一)
1.数学计算函数 abs(x) 求绝对值1.参数可以是整型,也可以是复数2.若参数是复数,则返回复数的模 complex([real[, imag]]) 创建一个复数 divmod(a, b) 分别取 ...
- 利用vue v-bind属性绑定bootstrap样式以及输出数据
自从知道了bootstrap,就被他简介,大气美观的样式吸引,即使在vue框架中,仍旧想使用,下面给出了vue适配版和原版的代码,以飨读者 数据输出部分 export default { data() ...
- [ML] The Basics: Training Your First Model
The problem we will solve is to convert from Celsius to Fahrenheit, where the approximate formula is ...
- ubunut:子进程 post-installation script 返回了错误号 1
解决dpkg/apt-get error : 子进程 post-installation script 返回了错误号 1 这个不太好解决,感觉这个比较好,未测试 https://blog.csdn.n ...
- JavaScript变量、作用域和内存问题总结
㈠理解基本类型和引用类型的值 ⑴JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值. ⑵基本类型的值源自以下 5 种基本数据类型:Undefined.Null.Boolean. ...
- PHP 字符串索引问题
php 通过下标获取的是字节,而不是字符!!!!$str{$i} 获取的是第$i个字节, 而不是第$i 个字符!!!哦 No,准确说是第$i+1个字节,因为下标是从0开始的,并且应该使用 []代替{} ...
- 最大的矩形(CCF)
问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi.这n个矩形构成了一个直方图.例如,下图中六个矩形的高度就分别是3, 1, 6, 5, 2, 3 ...
- [Luogu] 引水入城
https://www.luogu.org/problemnew/show/P1514 bfs + 线段覆盖 #include<bits/stdc++.h> using namespace ...