Java泛型笔记_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java泛型笔记

Java泛型笔记

 2015/5/10 3:12:28  Lucas_  程序员俱乐部  我要评论(0)
  • 摘要:泛型的本质:参数类型的应用。将所操作的数据类型定义为一个参数,并在应用的时候指定类型。1.为什么使用泛型在JDK1.5之前,泛型程序设计是通过继承来实现的,例如:Listlist=newArrayList();//当加入或取出元素时,都被当成Object类型来看待list.add(newInteger(10));list.add("10");那么,在取出元素时候,要知道取出元素的类型,并进行强制转换Integera=(Integer)list.get(0)
  • 标签:笔记 Java 泛型

泛型的本质:参数类型的应用。将所操作的数据类型定义为一个参数,并在应用的时候指定类型。

1.为什么使用泛型
? ? 在JDK1.5之前,泛型程序设计是通过继承来实现的,例如:? ?

class="java" name="code">List list = new ArrayList();	//当加入或取出元素时,都被当成Object类型来看待
list.add(new Integer(10));
list.add("10");

? ?那么,在取出元素时候,要知道取出元素的类型,并进行强制转换? ? ? ?

Integer a = (Integer) list.get(0); 	//要求强制转换成Integer类型
Integer b = (Integer) list.get(1);	//运行时报错 java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer


? ?如果使用泛型设计时,编译器进行参数检查

List<Integer> list = new ArrayList<Integer>();
list.add(new Integer(10));
list.add("10");  //编译器报错
list.add(10);

? 同样,取出时不用进行强制类型转换

Integer a = list.get(0);
Integer b = list.get(1);


泛型的优点:让编译器保留参数的类型信息,执行类型检查,执行类型转换操作。? 可读性+安全性提升。

2.泛型的类型擦除
? ? ?在Java源文件编译生成的字节码中是不包含泛型的类型信息的,即泛型只存在编译期。
? ? ?擦除后将泛型类型替换成限定类型(无限定类型的变量用Object)

List<Integer> list1 = new ArrayList<Integer>();
List<String> list2 = new ArrayList<String>();

System.out.println(list1.getClass() == list2.getClass());   // true
System.out.println(list1.getClass().getName());	//java.util.ArrayList
System.out.println(list2.getClass().getName());	//java.util.ArrayList

所以,List<Integer> 和 List<String>? 使用的是同一份字节码,它们在编译之后都会变成原始类型List。


3.泛型的继承: 不存在任何的继承关系


4.通配符类型


当要遍历一个集合的所有元素时:

void printCollection(Collection c) {
		Iterator it = c.iterator();
		for(int k=0; k<c.size(); k++) {
			System.out.println(i.next());
		}
	}


但泛型的版本只能接受元素类型为Object类型的集合void printCollection(Collection<Object> c),如果有ArrayList<String> 集合,则编译出错。
在老版本中可以打印任何类型的集合,设计人员设计了通配符"?"来搞定,使新版本也能遍历任何的类型。

void printCollection(Collection<?> c) {
		for(Object o : c) { 	//合法,因为存储类型一定是Object的子类型
			System.out.println(o);
		}	
	}


注:不能向Collection<?>容器实例中加入任何非null元素,因为编译器无法确定添加对象的类型

边界通配符: Producer Extends, Consumer Super
? ? ? ? ? 上界:ArrayList<? extends Number> collection = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?匹配Number类以及它的子类
? ? ? ? ? 下界:ArrayList<? super Integer> collection = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 匹配Integer类以及它的超类(Integer Number Object)
??
5.泛型的方法
? 拷贝一个数组中所有的对象到集合中的方法

 static void fromArraytoCollection(Object[] a, Collection<> c) {
  	for(Object o : a) {
  		c.add(o);  //Error	
  	}	
  }

?使用泛型方法

static <T> void fromArraytoCollection(Object[] a, Collection<T> c) {
  	for(T o : a) {
  		c.add(o);	
  	}	
  }


??
6.泛型的约束和局限性
? ? ?1) 泛型类的静态字段和静态方法无效、不能实例化对象、instanceOf操作

? ? ? ? ? ? 对 class GenericClass<T>
? ? ? ? ? ? 由于类型的擦除,JVM只有一个GenericClass类,所以GenericClass类的静态字段和静态方法的定义 ? ? ? ? ? ? 中不能使用T(多个),T只是与GencricClass实例相关的信息.
? ? ? ? ? ? T只在编译时被编译器理解,因此也就不能与运行时被JVM理解并执行其代表的操作的caozuofu.html" target="_blank">操作符(如instanceof 和new)联用

??? 2)不能出创建参数化类型数组

List<Integer>[] ls = new List<Integer>[10]; // error
List<?>[] ls = new List<?>[10];   //ok


? ?可以声明一个数组,然后进行强制转换

ls = (List<Integer>[])new List<?>[10];



?

发表评论
用户名: 匿名