前言
日常琐碎的时间下,不适合看一些长篇高质量的文章,但是琐碎时间也是时间,看一些短小精悍的文章来查缺补漏也是极好的。碎花化的时间,就交给“碎片化的文章”来填充吧。
今天“碎片化文章”主题:泛型-有限通配符。(推荐阅读时长5分钟 + 思考3分钟)
正文
关于泛型:,无限通配符:的概念这里就不做累述,咱们直接主题:有限通配符
- 上限通配符: extends Type>
- 下限通配符: super Type>
本文解决俩个问题:
- 1、无限通配符存在的问题
- 2、上下限通配符的不同
<code>public class TypeTest {
public void test(){
TypeTest.copy(new ArrayList<object>(),new ArrayList<string>());
TypeTest.copy(new ArrayList<string>(),new ArrayList<object>());
}
public staticvoid copy(List super T> dest, List extends T> src) { /<object>/<string>/<string>/<object>/<code>
for (int i = 0; i < src.size(); i++)
dest.set(i, src.get(i));
}
\tpublic static void copy2(List> dest, List> src) {
\tfor (int i=0; i<src.size> \tdest.set(i,src.get(i));
\t}
}/<src.size>
大家觉得这个TypeTest类有多少个错误?答案是俩个:
1、无限通配符存在的问题
第一个错误很简单: 对于 List>src来说,它的 get()可以取出任意类型(Object及其子类),毕竟它是无限通配符修饰。
对于 List>dest来说,它的 set()同样可以接受任意类型,“貌似”没有问题?
这里我们设想代码可以运行。对于dest和src来说,二者都是任意类型。
如果成功运行的代码, dest是 ArrayList<string>, src是 ArrayList<integer>,在运行期间通过 copy2()方法去拷贝 dest和 src。那么当dest尝试 get()时一定会崩溃!因为 dest是按自己期望类型String取,但是 src可不是按 dest的期望类型去存,所以我们一定会在运行期间遇到:/<integer>/<string>
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
因此IDE一般会在代码编写阶段禁止这种问题的出现!
2、上下限通配符的不同
由于上边提到的“宽松的方法签名”(无限通配符),也就引出了有限通配符,也就是demo代码中 publicstatic
这种写法就保证了上述的问题:
- 对于src来说,由于上限通配符的存在,只能 get()或 set()T及T的子类。
- 对于dest来说,由于下限通配符的存在,只能 get()或 set()T及T的父类。
在这个例子中,dest作为输出集合,get()方法只能得到T及T的父类,那么只要输入集合src提供的类型是T及T的子类,那么对于输出集合dest就一定没有问题。
这也就是demo代码中第2个错误出现的原因。
注意!!这部分内容只是解释 和 的异同帮助大家理解有限通配符,在使用的时候还是要具体情况具体分析。
尾声
OK,结束的很突然?没错就是这么突然,接下来的时间,大家可以关掉手机花个两三分钟想一想刚才的内容,想明白了,也就有收获了~
閱讀更多 碼農登陸 的文章