关于java泛型的小测试(wildcard,erasure,covariant,raw type)

java的泛型机制让人头大,很难搞,我也生晚,见识也浅,权且抛砖引玉,望各位看官多多指点!

从测试中暂时得到的几个小结论:
  • 原生类型与<?>并不相同,从测试中的warning可以看到这一点;
  •           其一,原生类型会擦除其所有实例成员的泛型参数;
              其二,<?>代表我要使用泛型,而不是原生类型;
              其三,<Object>与<?>也不相同。
              详细内容可以参见这两篇文章 http://blog.sina.com.cn/s/blog_65554d980100ijft.html
                                                                  http://blog.csdn.net/yinbodotcc/article/details/1492493
  • 数组会发生协变,而泛型不会发生协变。
  • 在捕获转换时一定要使用<?>,而不是原生类型。
  • 泛型有其存在的意义,但是使用时要倍要小心,否则适得其反。
  • 原生类型并非一无是处:其对于解决java兼容其早期版本意义重大。

这是测试,小弟边看边写,封装太差,见笑见笑。

/**
 * @Title: Generic29.java
 * @Package com.generic
 * @Description: TODO(test generic class)
 * @author BUPTLXB  
 * @date 2012-7-14 下午4:59:40
 * @version V1.0   
 */
package com.generic;

import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName Holder
 * @Description TODO(a classic generic class) 
 * @author BUPTLXB
 * @TimeStamp 2012-7-14 下午5:00:43
 *
 */
class Holder <T>{
	private T value;
	public Holder(){}
	public Holder(T value){
		this.value = value;
	}
	public void set(T value){
		this.value = value;
	}
	public T get(){
		return value;
	}
	public boolean equals(Object obj){
		return value.equals(obj);
	}
}
/**
 * @ClassName Generic29
 * @Description TODO(test running class) 
 * @author BUPTLXB
 * @TimeStamp 2012-7-14 下午4:59:40
 *
 */
public class Generic29 {
	
	/**
	 * @Title: display
	 * @Description: TODO(display the type information of objs)
	 * @param objs : a set of instance 
	 * @throws
	 * @date 2012-7-14 下午5:42:14
	 */
	private static void display(Object...objs){
		for(Object o : objs){
			System.out.print("getSimpleName():"+o.getClass().getSimpleName()
					+"\t|\t"+o+"\t|\t getTypeParameters():");
			for(TypeVariable<?> tv : o.getClass().getTypeParameters()){
				System.out.print(" "+tv);
			}
			System.out.println();
		}
	}
	
	/**
	 * @Title: generic1
	 * @Description: TODO(test1)
	 * @param h : a classic generic class under test
	 * @throws
	 * @date 2012-7-14 下午5:44:57
	 */
	public static void generic1(Holder<List<?>> h){
		System.out.println("-----------------------void generic1(Holder<List<?>> h)-----------------------");
		//Warning : Holder is a raw type. References to generic type Holder<T> should be parameterized
		Holder holder1 = h;
		Holder<?> holder2 = h;
		//Error : Type mismatch: cannot convert from Holder<List<?>> to Holder<List>
		//Holder<List> holder4 = h;
		//Warning : List is a raw type. References to generic type List<E> should be parameterized
		Holder<List> holder3 = holder1;
		display("========Holder==========",h,holder1,holder2,holder3,"========================");
		
		display("========list1===========",h.get(),holder1.get(),holder2.get(),holder3.get(),"========================");
		List<?> list1 = h.get();
		display("=====list1.element======",list1.get(0),list1.get(1),list1.get(2),"========================");
		
		h.set(Arrays.asList('a','b','c'));
		display("========list2===========",h.get(),holder1.get(),holder2.get(),holder3.get(),"========================");
		List<?> list2 = h.get();
		display("=====list2.element======",list2.get(0),list2.get(1),list2.get(2),"========================");
		
		//Warning : Type safety: The method set(Object) belongs to the raw type Holder. References to generic type Holder<T> should be parameterized.
		holder1.set(Arrays.asList("abc","bcd","efg"));
		display("========list3===========",h.get(),holder1.get(),holder2.get(),holder3.get(),"========================");
		List<?> list3 = h.get();
		display("=====list3.element======",list3.get(0),list3.get(1),list3.get(2),"========================");
		//Error : The method set(capture#5-of ?) in the type Holder<capture#5-of ?> is not applicable for the arguments (List<capture#6-of ?>)
		//holder2.set(list);
		
		holder3.set(Arrays.asList(list1,list2,list3));
		display("========list4===========",h.get(),holder1.get(),holder2.get(),holder3.get(),"========================");
		List<?> list4 = h.get();
		display("=====list4.element======",list4.get(0),list4.get(1),list4.get(2),"========================");
	}
	
	/**
	 * @Title: generic2
	 * @Description: TODO(test2)
	 * @param list a classic generic class under test
	 * @throws
	 * @date 2012-7-14 下午7:26:57
	 */
	public static void generic2(List<Holder<?>> list){
		System.out.println("-----------------------generic2(List<Holder<?>> list) is invoked!-----------------------");
		List list1 = list;
		List<?> list2 = list;
		List<Holder> list3 = list1;//Be careful!
		display("========list============",list,list1,list2,list3,"========================");
		display("=====list.element=======",list.get(0),list.get(1),list.get(2),"========================");
		display("=====list1.element======",list1.get(0),list1.get(1),list1.get(2),"========================");
		display("=====list2.element======",list2.get(0),list2.get(1),list2.get(2),"========================");
		display("=====list3.element======",list3.get(0),list3.get(1),list3.get(2),"========================");
		display("==list.element.value====",list.get(0).get(),list.get(1).get(),list.get(2).get(),"========================");
		//The method get() is undefined for the type Object	Generic29.java	
		//display("==list.element.value====",list1.get(0).get(),list1.get(1).get(),list1.get(2).get(),"========================");
		//display("==list.element.value====",list2.get(0).get(),list2.get(1).get(),list2.get(2).get(),"========================");
		display("==list3.element.value===",list3.get(0).get(),list3.get(1).get(),list3.get(2).get(),"========================");
		try {
			list.add(new Holder<>());
			display("========list.size=======",list.size());
			list1.add(new Object());
			display(list1.size());
			list2.add(null);
			display(list2.size());
			list3.add(new Holder<>());
			display(list3.size(),"========================");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	
	/** @Title: main
	 * @Description: TODO(description of the method)
	 * @param args void
	 * @throws
	 * @date 2012-7-14 下午4:59:40
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		generic1(new Holder<List<?>>(Arrays.asList(1,2,3)));
		List<Holder<?>> list = new ArrayList<Holder<?>>();
		list.add(new Holder<>('a'));
		list.add(new Holder<Integer>(0));
		list.add(new Holder<String>("abc"));
		generic2(list);
	}

}



运行结果:

-----------------------void generic1(Holder<List<?>> h)-----------------------
getSimpleName():String	|	========Holder==========	|	 getTypeParameters():
getSimpleName():Holder	|	com.generic.Holder@3fa5ac	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@3fa5ac	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@3fa5ac	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@3fa5ac	|	 getTypeParameters(): T
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	========list1===========	|	 getTypeParameters():
getSimpleName():ArrayList	|	[1, 2, 3]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[1, 2, 3]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[1, 2, 3]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[1, 2, 3]	|	 getTypeParameters(): E
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list1.element======	|	 getTypeParameters():
getSimpleName():Integer	|	1	|	 getTypeParameters():
getSimpleName():Integer	|	2	|	 getTypeParameters():
getSimpleName():Integer	|	3	|	 getTypeParameters():
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	========list2===========	|	 getTypeParameters():
getSimpleName():ArrayList	|	[a, b, c]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[a, b, c]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[a, b, c]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[a, b, c]	|	 getTypeParameters(): E
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list2.element======	|	 getTypeParameters():
getSimpleName():Character	|	a	|	 getTypeParameters():
getSimpleName():Character	|	b	|	 getTypeParameters():
getSimpleName():Character	|	c	|	 getTypeParameters():
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	========list3===========	|	 getTypeParameters():
getSimpleName():ArrayList	|	[abc, bcd, efg]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[abc, bcd, efg]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[abc, bcd, efg]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[abc, bcd, efg]	|	 getTypeParameters(): E
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list3.element======	|	 getTypeParameters():
getSimpleName():String	|	abc	|	 getTypeParameters():
getSimpleName():String	|	bcd	|	 getTypeParameters():
getSimpleName():String	|	efg	|	 getTypeParameters():
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	========list4===========	|	 getTypeParameters():
getSimpleName():ArrayList	|	[[1, 2, 3], [a, b, c], [abc, bcd, efg]]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[[1, 2, 3], [a, b, c], [abc, bcd, efg]]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[[1, 2, 3], [a, b, c], [abc, bcd, efg]]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[[1, 2, 3], [a, b, c], [abc, bcd, efg]]	|	 getTypeParameters(): E
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list4.element======	|	 getTypeParameters():
getSimpleName():ArrayList	|	[1, 2, 3]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[a, b, c]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[abc, bcd, efg]	|	 getTypeParameters(): E
getSimpleName():String	|	========================	|	 getTypeParameters():
-----------------------generic2(List<Holder<?>> list) is invoked!-----------------------
getSimpleName():String	|	========list============	|	 getTypeParameters():
getSimpleName():ArrayList	|	[com.generic.Holder@1742700, com.generic.Holder@acb158, com.generic.Holder@1af33d6]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[com.generic.Holder@1742700, com.generic.Holder@acb158, com.generic.Holder@1af33d6]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[com.generic.Holder@1742700, com.generic.Holder@acb158, com.generic.Holder@1af33d6]	|	 getTypeParameters(): E
getSimpleName():ArrayList	|	[com.generic.Holder@1742700, com.generic.Holder@acb158, com.generic.Holder@1af33d6]	|	 getTypeParameters(): E
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list.element=======	|	 getTypeParameters():
getSimpleName():Holder	|	com.generic.Holder@1742700	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@acb158	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@1af33d6	|	 getTypeParameters(): T
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list1.element======	|	 getTypeParameters():
getSimpleName():Holder	|	com.generic.Holder@1742700	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@acb158	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@1af33d6	|	 getTypeParameters(): T
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list2.element======	|	 getTypeParameters():
getSimpleName():Holder	|	com.generic.Holder@1742700	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@acb158	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@1af33d6	|	 getTypeParameters(): T
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	=====list3.element======	|	 getTypeParameters():
getSimpleName():Holder	|	com.generic.Holder@1742700	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@acb158	|	 getTypeParameters(): T
getSimpleName():Holder	|	com.generic.Holder@1af33d6	|	 getTypeParameters(): T
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	==list.element.value====	|	 getTypeParameters():
getSimpleName():Character	|	a	|	 getTypeParameters():
getSimpleName():Integer	|	0	|	 getTypeParameters():
getSimpleName():String	|	abc	|	 getTypeParameters():
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	==list3.element.value===	|	 getTypeParameters():
getSimpleName():Character	|	a	|	 getTypeParameters():
getSimpleName():Integer	|	0	|	 getTypeParameters():
getSimpleName():String	|	abc	|	 getTypeParameters():
getSimpleName():String	|	========================	|	 getTypeParameters():
getSimpleName():String	|	========list.size=======	|	 getTypeParameters():
getSimpleName():Integer	|	4	|	 getTypeParameters():
getSimpleName():Integer	|	5	|	 getTypeParameters():
getSimpleName():Integer	|	6	|	 getTypeParameters():
getSimpleName():Integer	|	7	|	 getTypeParameters():
getSimpleName():String	|	========================	|	 getTypeParameters():



欢迎拍砖!

你可能感兴趣的:(java,generic,wildcard,Covariant,erasure)