`
InvocationHandler
  • 浏览: 36359 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
  • java
阅读更多
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泛型的用法及T.class的获取过程解析

    Java泛型的用法及T.class的获取过程解析 Java泛型是Java编程语言中的一种重要特性,它允许开发者在编写代码时指定类型参数,从而提高代码的灵活性和可读性。本文将详细介绍Java泛型的用法 及T.class的获取过程解析...

    JAVA泛型加减乘除

    这是一个使用JAVA实现的泛型编程,分为两部分,第一部分创建泛型类,并实例化泛型对象,得出相加结果。 第二部分用户自行输入0--4,选择要进行的加减乘除运算或退出,再输入要进行运算的两个数,并返回运算结果及...

    很好的Java泛型的总结

    Java泛型机制详解 Java泛型是Java语言中的一种机制,用于在编译期检查类型安全。Java泛型的出现解决了Java早期版本中类型安全检查的缺陷。Java泛型的好处是可以在编译期检查类型安全,避免了运行时的...

    Java泛型应用实例

    Java泛型是Java编程语言中的一个强大特性,它允许我们在定义类、接口和方法时指定类型参数,从而实现代码的重用和类型安全。在Java泛型应用实例中,我们可以看到泛型如何帮助我们提高代码的灵活性和效率,减少运行时...

    Java泛型三篇文章,让你彻底理解泛型(super ,extend等区别)

    Java 泛型详解 Java 泛型是 Java SE 5.0 中引入的一项特征,它允许程序员在编译时检查类型安全,从而减少了 runtime 错误的可能性。泛型的主要优点是可以Reusable Code,让程序员编写更加灵活和可维护的代码。 ...

    1.java泛型定义.zip

    1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....

    java泛型深入.pdf

    Java泛型是Java语言中用于处理类型安全的一种机制,它允许在编译期间提供类型检查,并在运行时消除了类型转换。Java泛型深入的内容涵盖泛型的基本概念、泛型类、接口、方法以及泛型的使用限制和高级特性。 首先,...

    java泛型技术之发展

    4. 普及与优化:随着Java泛型的广泛应用,JDK 6和7对其进行了进一步优化,如类型推断(Type Inference),使得编写泛型代码更加简洁。 二、核心概念 1. 泛型类:可以带有类型参数的类,例如`ArrayList&lt;T&gt;`,这里的...

    关于java基础的泛型的练习

    Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全...在进行"关于Java基础的泛型的练习"时,可以尝试编写不同的泛型类、泛型方法,体验泛型带来的便利,并理解其背后的类型系统和类型擦除机制。

    java 泛型方法使用示例

    Java 泛型是Java SE 5.0引入的一项重要特性,极大地增强了代码的类型安全性和重用性。泛型方法是泛型技术在类方法层面的应用,它允许我们定义一个可以处理多种数据类型的通用方法。下面我们将深入探讨Java泛型方法的...

    java 泛型接口示例

    Java 泛型是Java SE 5.0引入的一项重要特性,极大地增强了代码的类型安全性和重用性。泛型接口是泛型在接口中的应用,它允许我们在接口中定义带有类型参数的方法,使得实现该接口的类可以使用不同的数据类型。下面...

    4.java泛型的限制.zip

    4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip...

    java 泛型类的类型识别示例

    综上所述,虽然Java泛型在编译后会进行类型擦除,但通过上述技巧,我们仍然能够在运行时获得关于泛型类实例化类型的一些信息。在实际开发中,这些方法可以帮助我们编写更加灵活和安全的代码。在示例文件`GenericRTTI...

    java泛型的内部原理及更深应用

    Java泛型是Java编程语言中的一个强大特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。这使得代码更加安全、可读性更强,并且能够减少类型转换的必要。在“java泛型的内部原理及更深应用”这个...

    关于C#、java泛型的看法

    在编程世界中,C#和Java都是广泛应用的高级编程语言,它们都支持泛型这一强大的特性,以提高代码的类型安全性和重用性。本文将深入探讨C#和Java在泛型实现上的异同,帮助开发者更好地理解和利用这两种语言的泛型功能...

Global site tag (gtag.js) - Google Analytics