zoukankan      html  css  js  c++  java
  • Java Generics and Collections-8.1

    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专家。

  • 相关阅读:
    测试开发之利器论战
    测试开发的战略战术
    Python日志Logging
    Android自动测试中的monkey工具使用方法
    ADB命令讲解
    学习要深入
    测试开发发展感触
    Web Service测试工具小汇
    python接口测试浅谈
    手机上app测试总结(转)
  • 原文地址:https://www.cnblogs.com/xiaojintao/p/5302163.html
Copyright © 2011-2022 走看看