8.1 Take Care when Calling Legacy Code

通常,泛型都是在编译时检查的,而不是运行时。便意识检查可以提早通知错误,而不至于到运行时才出问题。

但有时后编译时检查不一定就坚不可摧,因为有时我们在运行时才能之道具体类型。

(唉,翻译水平有限,还是看代码吧)

package java_generics_collections.chap08;

import java.util.ArrayList;
import java.util.List; /**
* Created by jintaox on 2016/3/21.
*/
public class LegacyLibrary {
public static void addItems(List list) {
list.add(new Integer(1));
list.add("two");
} public static List getItems() {
List list = new ArrayList();
list.add(new Integer(3));
list.add("four");
return list;
}
}
使用这段代码的客户端被告知item永远是整数。
package java_generics_collections.chap08;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List; /**
* Created by jintaox on 2016/3/21.
*/
public class NaiveClient {
public static void processItems() {
List<Integer> list = new ArrayList<>();
LegacyLibrary.addItems(list);
List<Integer> list2 = LegacyLibrary.getItems();//unchecked warnings
//sometime later可能过了很久才打算使用list中的数据
int s = 0;
for (int i : list) {
s += i;//class cast exception
}
for (int i : list2) {
s += i;//class cast exception
}
} @Test
public void test_processItems() throws Exception {
processItems();
}
}
当我们对这段代码跑测试的时候,异常如下:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at java_generics_collections.chap08.NaiveClient.processItems(NaiveClient.java:18)
at java_generics_collections.chap08.NaiveClient.test_processItems(NaiveClient.java:28)
...
也就是说我们从集合中拿出数据并把它当作`Integer`来用的时候,它抛出了异常,也就是说错误定位我们只能快速到达这里,但究其原因是因为我们在插入的时候,插入了一个`String`类型,
而我们很难定位到这里,只能从头开始读代码。 来看另一个客户端(以下代码是可以通过编译检查)
package java_generics_collections.chap08;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List; /**
* Created by jintaox on 2016/3/21.
*/
public class WaryClient {
public static void processItems() {
List<Integer> list = new ArrayList<>();
List<Integer> view = Collections.checkedList(list, Integer.class);
LegacyLibrary.addItems(view);
List<Integer> list2 = LegacyLibrary.getItems();//unchecked
for (int i : list2) {
//class case exception
System.out.println(i);
} } @Test
public void test_processItems() throws Exception {
processItems();
}
}
在这个客户端里面,我们使用了工具类`Collections`中的`checkedList`方法,还是先看运行结果吧
java.lang.ClassCastException: Attempt to insert class java.lang.String element into collection with element type class java.lang.Integer
at java.util.Collections$CheckedCollection.typeCheck(Collections.java:3037)
at java.util.Collections$CheckedCollection.add(Collections.java:3080)
at java_generics_collections.chap08.LegacyLibrary.addItems(LegacyLibrary.java:12)
at java_generics_collections.chap08.WaryClient.processItems(WaryClient.java:16)
at java_generics_collections.chap08.WaryClient.test_processItems(WaryClient.java:27)
看,我们一下就定位到了插入的地方,这样就大大加快我们定位错误的速度。
`checkedList`方法的api介绍: Returns a dynamically typesafe view of the specified collection.

checkedList源码分析待定

加油,我要做Java专家。

Java Generics and Collections-8.1的更多相关文章

  1. python 中的sort 和java中的Collections.sort()函数的使用

    x=[1,2,3] x.sort()对的,x这个都变了 y=x.sort()错误 y=sorted(x)对的,x拍好序的一个副本 python中用匿名函数和自定义函数排序:(很奇怪的是比较函数返回的是 ...

  2. Java Concurrency - Concurrent Collections

    Data structures are a basic element in programming. Almost every program uses one or more types of d ...

  3. thinking in java Generics Latent typing

    The beginning of this chapter introduced the idea of writing code that can be applied as generally a ...

  4. Thinking in java——Generics

    ​Ordinary classes and methods work with specific types: either primitives or class types. If you are ...

  5. 【Java】Java中的Collections类——Java中升级版的数据结构【转】

    一般来说课本上的数据结构包括数组.单链表.堆栈.树.图.我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,String,double甚至一维数组.二维数 ...

  6. Java中的Collections类

    转载:https://blog.csdn.net/yangxingpa/article/details/80515963 从[Java]Java中的Collections类——Java中升级版的数据结 ...

  7. Java Generics and Collections-2.3

    2.3 Wildcards with super 这里就直接拿书上的例子好了,这是Collections里面的一个方法: public static <T> void copy(List& ...

  8. java List 排序 Collections.sort() 对 List 排序

    class User { String name; String age;  public User(String name,String age){  this.name=name;  this.a ...

  9. 黑马程序员——JAVA基础之Collections和Arrays,数组集合的转换

    ------- android培训.java培训.期待与您交流! ---------- 集合框架的工具类:        Collections : 集合框架的工具类.里面定义的都是静态方法. Col ...

随机推荐

  1. # ASP.NET Core依赖注入解读&使用Autofac替代实现

    标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...

  2. C#正则表达式验证

    public class VerifyUtil { /// <summary> /// 判断输入的字符串只包含汉字 /// </summary> /// <param n ...

  3. Android按返回键退出程序但不销毁,程序后台保留

    重写onKeyDown事件即可 @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyE ...

  4. 微信JSApi支付~订单号和微信交易号

    返回目录 谈谈transactionId和out_trade_no 前一篇微信JSApi支付~坑和如何填坑文章反映不错,所以又写了个后篇,呵呵. 每个第三方在线支付系统中都会有至少两类订单号,其一为支 ...

  5. 转载:《TypeScript 中文入门教程》 6、命名空间

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变 ...

  6. codevs 1021 玛丽卡(spfa)

    题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...

  7. linux下tomcat安全配置

    转:http://www.tuicool.com/articles/R7fQNfQ 0x00 删除默认目录 安装完tomcat后,删除 $CATALINA_HOME/webapps 下默认的所有目录文 ...

  8. (原) 2.1 Zookeeper原生API使用

    本文为原创文章,转载请注明出处,谢谢 Zookeeper原生API使用 1.jar包引入,演示版本为3.4.6,非maven项目,可以下载jar包导入到项目中 <dependency> & ...

  9. link与@import的区别

    我们都知道link与@import都可以引入css样式表,那么这两种的区别是什么呢?先说说它们各自的链接方式,然后说说它们的区别~~~ link链入的方式: <link rel="st ...

  10. js for循环中i++ 和 ++i有什么区别?

    平时都是这样写的for循环, for(var i = 0; i < 20 ; i++){ .... } 但我看有的人这样写 for (var i = 0; i < 20 ; ++i) { ...