码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-01-31 21:52:08      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

 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         @Override
100         public String toString() {
101             return "GenericeClass [t=" + t + "]";
102         }
103 
104     }
105 
106     /**
107      * 测试泛型集合
108      */
109     @Test
110     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      * @return
124      */
125     private <E> Collection<E> createCollection(E t) {
126         // TODO Auto-generated method stub
127         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>) Arrays
133                     .asList(new String[] { "测试集合1", "测试集合2", "测试集合3" });
134             collection.addAll(initData);
135         }
136         return collection;
137     }
138 
139     /**
140      * 创建Number集合
141      * 此方法不推荐使用 这里只是测试使用  
142      * @return
143      */
144     @Deprecated
145     private <E> Collection<E> createNumber() {
146         Collection<E> collection = new CopyOnWriteArrayList<E>();
147         @SuppressWarnings("unchecked")
148         Collection<? extends E> initData = (Collection<? extends E>) Arrays
149                 .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 src
159      */
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-super
169      */
170     @Test
171     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.out
180                 .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.out
188                 .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.out
196                 .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.out
202                 .println("之前一直有个疑惑,为什么Collection<Number>、Collection<Integer>、Collection<String>、Collection<Serializable>、Collection<List>调用的时候 能够返回相应的集合,"
203                         + "因为很明显 在createNumber方法中创建的是Number的List<Number>集合 我们有知道泛型是不可协变的 为什么会成功呢 ");
204         System.out
205                 .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.List
212      */
213     @Test
214     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     @Test
225     public void testOther() {
226         Integer integer = (int) 13.2;
227         String aString = String.valueOf(13.2);
228     }
229 
230 }

 

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

标签:

原文地址:http://www.cnblogs.com/liangxinzhi/p/java_generics.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!