Java Generics and Collections-8.1
2016-03-21 15:32
483 查看
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 Web入门笔记及实例
- 深度分析 Java 的 ClassLoader 机制(源码级别)
- java io exception Broken Pipe
- Java异常的深入研究与分析
- Java并发编程:线程池的使用
- LinkedHashMap超详细分析
- java中String字符串的替换函数:replace与replaceAll的区别
- Java枚举常见7种用法
- JAVA中string.replace()和string.replaceAll()的区别及用
- Java RMI 简单示例
- 手把手教你整合 SpringMvc+Spring+MyBatis+Maven
- Struts 2 + Hibernate + Spring 整合要点
- Struts2 入门实例
- java 学习笔记
- Spring MVC 实践笔记
- Java数据库
- 关于java中Double类型的运算精度问题(转)
- 数组复制引用问题
- java基础经典练习题
- java线程研究