当前位置: 代码迷 >> Java相关 >> java之泛型了解(高效java之泛型)
  详细解决方案

java之泛型了解(高效java之泛型)

热度:97   发布时间:2016-04-22 20:44:13.0
java之泛型理解(高效java之泛型)
 1  * 泛型-->类或者接口的声明中拥有一个或多个类型参数时,称为泛型类/泛型接口,简称泛型  2  * 泛型在安全性和表述性上都比原生态类型更具有优势 3  * 泛型是不可变的,无法向数组一样形成协变关系  4  * (Sub extends Super,同时可支持Sub[] extends Super[])  5  * (Sub extends Super,不支持List<Sub> extends List<Super>)  6  * 泛型在编译时检查其元素类型信息,而在运行期舍弃其元素类型信息 7  *  每个类都是自身的子类型和超类型 8  * T 形式类型参数  9  * E 集合中的形式类型参数 10  * K Map中的键形式参数 11  * V Map中的值形式参数 12  * ? 任意匹配的配型参数 <? extends E>/<? super E>13  * 有限的通配符形式参数(PECS)14  * 15  * Class<T> 泛型 16  * Class<String> 参数化的类型 17  * Class 原生态类型(删除了所有的泛型信息) 18  * Class<?> 无限制的通配符类型19  * Class<? extends E> 有限制的通配符类型20  *  <T> 形式类型参数 21  *  <String> 实际类型参数22  * 23  * static <E> E get(E e) 泛型方法24  *  (<E> 称为类型参数列表,即在调用方法之前告诉编译器,此方法中的类型都是什么类型)25  * 编译器使用泛型方法可通过类型推导,推导出类型参数列表的类型

 

 

测试代码

  1 package com.undergrowth.lang;  2   3 import java.io.Serializable;  4 import java.util.Arrays;  5 import java.util.Collection;  6 import java.util.Collections;  7 import java.util.List;  8 import java.util.concurrent.CopyOnWriteArrayList;  9  10 import org.junit.Test; 11  12 /** 13  * 泛型学习测试代码 14  *  15  * 泛型-->类或者接口的声明中拥有一个或多个类型参数时,称为泛型类/泛型接口,简称泛型  16  * 泛型在安全性和表述性上都比原生态类型更具有优势 17  * 泛型是不可变的,无法向数组一样形成协变关系  18  * (Sub extends Super,同时可支持Sub[] extends Super[])  19  * (Sub extends Super,不支持List<Sub> extends List<Super>)  20  * 泛型在编译时检查其元素类型信息,而在运行期舍弃其元素类型信息 21  *  每个类都是自身的子类型和超类型 22  * T 形式类型参数  23  * E 集合中的形式类型参数  24  * K Map中的键形式参数  25  * V Map中的值形式参数  26  * ? 任意匹配的配型参数 <? extends E>/<? super E> 27  * 有限的通配符形式参数(PECS) 28  *  29  * Class<T> 泛型  30  * Class<String> 参数化的类型  31  * Class 原生态类型(删除了所有的泛型信息)  32  * Class<?> 无限制的通配符类型 33  * Class<? extends E> 有限制的通配符类型 34  *  <T> 形式类型参数  35  *  <String> 实际类型参数 36  *  37  * static <E> E get(E e) 泛型方法 38  *  (<E> 称为类型参数列表,即在调用方法之前告诉编译器,此方法中的类型都是什么类型) 39  * 编译器使用泛型方法可通过类型推导,推导出类型参数列表的类型 40  *  41  * 此内容主要涉及泛型类和泛型方法,测试用例-->testGenericeClass 42  * 泛型集合-->testGeneCollection 43  * 有限的通配符使用-->testBoundWildType 44  * 泛型编译器维护类型信息,运行时舍弃-->testEraseGenericsInfo 45  *  46  * @author Administrator 47  *  48  */ 49 public class GenericsLearn { 50  51     /** 52      * 测试泛型类和方法 53      */ 54     @Test 55     public void testGenericeClass() { 56         GenericeClass<String> gClass1 = new GenericeClass<String>("测试泛型类参数"); 57         System.out.println(gClass1); 58         System.out.println(gClass1.getAddSome("泛型方法")); 59         System.out.println(gClass1.getAddSome(123)); 60     } 61  62     /** 63      * 泛型测试类 64      *  65      * @author Administrator 66      *  67      * @param <T> 68      */ 69     private static class GenericeClass<T> { 70         private final T t; 71  72         public GenericeClass(T t) { 73             super(); 74             this.t = t; 75         } 76  77         /** 78          * 获取对象后 添加附加信息 79          *  80          * @param t 81          * @return 82          */ 83         public <E> E getAddSome(E t) { 84             if (t instanceof String) { 85                 // 因为在进入此方法时 已做了类型判断 使用注解消除非受检警告 86                 @SuppressWarnings("unchecked") 87                 E t1 = (E) (String.valueOf(t) + ",附加泛型防范新消息"); 88                 return t1; 89             } 90             return t; 91         } 92  93         public void iterator(Iterable<? extends T> src) { 94             for (T t : src) { 95                 System.out.println(t); 96             } 97         } 98  99         @Override100         public String toString() {101             return "GenericeClass [t=" + t + "]";102         }103 104     }105 106     /**107      * 测试泛型集合108      */109     @Test110     public void testGeneCollection() {111         Collection<String> collection = createCollection("123");112         /*113          * for (Iterator<String> iterator = collection.iterator();114          * iterator.hasNext();) { String string = (String) iterator.next();115          * System.out.println(string); }116          */117         iterator(collection);118     }119 120     /**121      * 创建测试集合122      * 123      * @return124      */125     private <E> Collection<E> createCollection(E t) {126         // TODO Auto-generated method stub127         Collection<E> collection = Collections.emptyList();128         if (t instanceof String) {129             collection = new CopyOnWriteArrayList<E>();130             // 已经进行类类型检查 所以转换时没有问题的 每个类都是自身的子类型和超类型131             @SuppressWarnings("unchecked")132             Collection<? extends E> initData = (Collection<? extends E>) Arrays133                     .asList(new String[] { "测试集合1", "测试集合2", "测试集合3" });134             collection.addAll(initData);135         }136         return collection;137     }138 139     /**140      * 创建Number集合141      * 此方法不推荐使用 这里只是测试使用  142      * @return143      */144     @Deprecated145     private <E> Collection<E> createNumber() {146         Collection<E> collection = new CopyOnWriteArrayList<E>();147         @SuppressWarnings("unchecked")148         Collection<? extends E> initData = (Collection<? extends E>) Arrays149                 .asList(new Number[] { 123.2, Integer.MAX_VALUE, 789 });150         // System.out.println(initData.getClass().getName());151         collection.addAll(initData);152         return collection;153     }154 155     /**156      * 迭代实现了Iterable接口的可迭代子类157      * 158      * @param src159      */160     public <E> void iterator(Iterable<E> src) {161         for (E e : src) { // 内部通过迭代器来遍历元素162             System.out.println(e);163         }164     }165 166     /**167      * 测试有限的通配符类型 每个类都是自身的子类型和超类型168      *  PECS原则-->producer-extends,consumer-super169      */170     @Test171     public void testBoundWildType() {172         GenericeClass<Number> gClass1 = new GenericeClass<Number>(123456);173         System.out.println(gClass1);174         System.out.println(gClass1.getAddSome("123456"));175         // 创建Number数组176         Collection<Number> collection = createNumber();177         iterator(collection);178         // 使用GenericeClass的迭代方法进行迭代 每个类都是自身的子类型和超类型179         System.out180                 .println("使用有限的通配符进行迭代 形式为:Iterable<? extends T>  实际为:Iterable<Number extends Number> 每个类都是自身的子类型和超类型");181         gClass1.iterator(collection);182         Collection<Integer> collection2 = createNumber();183         // 使用foreach进行迭代184         System.out.println("使用foreach进行迭代");185         iterator(collection2);186         // 使用有限的通配符进行迭代187         System.out188                 .println("使用有限的通配符进行迭代 形式为:Iterable<? extends T>  实际为:Iterable<Integer extends Number>");189         gClass1.iterator(collection2);190         System.out.println("进行字符串集合的foreach迭代");191         Collection<String> collection3 = createNumber();192         iterator(collection3);193         System.out.println("如果使用collection3.add(123)方法,泛型的安全性检查就会得到体现,编译器会报错");194         // collection3.add(123);195         System.out196                 .println("如果调用gClass1.iterator(collection3)方法,就会有问题,因为形式为:Iterable<? extends T> 实际为:Iterable<String extends Number>");197         // gClass1.iterator(collection3);198         System.out.println("获取Serializable集合");199         Collection<Serializable> collection4 = createNumber();200         iterator(collection4);201         System.out202                 .println("之前一直有个疑惑,为什么Collection<Number>、Collection<Integer>、Collection<String>、Collection<Serializable>、Collection<List>调用的时候 能够返回相应的集合,"203                         + "因为很明显 在createNumber方法中创建的是Number的List<Number>集合 我们有知道泛型是不可协变的 为什么会成功呢 ");204         System.out205                 .println("因为泛型在编译器检查其类型信息(所以当定义Collection<Serializable> collection4 = createNumber();的时候 调用createNumber,而此方法只会进行类型检查,createNumber为泛型方法,所以编译时是没有问题的),而在运行时丢弃其元素类型信息,并且强制类型转换是在运行期进行的,所以在(Collection<? extends E>)强制类型转换实际上是(Collection)List,所以运行期也没有问题,调试一下就知道了,害我想了1个多小时");206     }207 208     /**209      * 测试泛型只在编译器维护其类型信息 在运行期不会维护其元素的类型信息 210      * 下面代码会报错 java.lang.ClassCastException:211      * java.lang.Double cannot be cast to java.util.List212      */213     @Test214     public void testEraseGenericsInfo() {215         System.out.println("获取List集合");216         Collection<List> collection5 = createNumber();217         for (List list : collection5) {218             System.out.println(list.get(0));219             ;220         }221     }222     223     224     @Test225     public void testOther() {226         Integer integer = (int) 13.2;227         String aString = String.valueOf(13.2);228     }229 230 }

 

  相关解决方案