内容:Java中的泛型
优秀文章:
新浪博客-海洋星球:http://blog.sina.com.cn/s/blog_44c1e6da0100cus3.html
书籍:细说Java、疯狂Java讲义
说明:
泛型是于Java SE1.5添加的新特性;
泛型的本质是参数化类型,简单来说就是将泛型看作一个或多个参数,使用这个参数的代码片段可以由任何具体类类型的参数来替换;
泛型的参数类型只能是类类型,不能是简单类型(简单类型是指不能再简化的编程语言内置数据类型,java中有实数-float-double、整数-byte-short-int-long、字符-char、布尔值-boolean);
泛型可以用于接口(成员属性)、类(成员属性)、方法(返回值)的定义中,分别称作泛型接口、泛型类、泛型方法;
泛型的使用可以提高代码的重用性;
泛型信息主要作用于编译阶段,对于运行时期,泛型的信息则会丢失(类型擦除);
泛型常用与集合中;
使用:
1.确保数据的合法性(集合中存放元素时不会对存放的数据进行判断,即不同的数据类型可以毫无区分的存入集合中);
2.集合元素的类型指定(集合中已存入的元素默认情况下都是Ob类型,因此每次取值时都需要进行数据转换,且每个元素的数据类型都要清楚的知晓);
1 import java.util.LinkedList; 2 import java.util.List; 3 4 5 public class DemoList { 6 //传统程序 7 public List getList01(){ 8 List list = new LinkedList(); 9 //任何值都可以存入集合,若取值时转化有误,则产生异常; 10 list.add("一"); 11 list.add(2); 12 return list; 13 } 14 //使用泛型 15 public List<String> getList02(){ 16 List<String> list = new LinkedList<String>(); 17 //非参数类型值不可存,限制了集合的元素类型; 18 list.add("one"); 19 list.add("tow"); 20 return list; 21 } 22 23 public static void main(String[] args) { 24 // TODO Auto-generated method stub 25 DemoList dl = new DemoList(); 26 List l1 = dl.getList01(); 27 //每次取值都需要进行强转 28 String s0 = (String)l1.get(0); 29 int s1 = (int) l1.get(1); 30 System.out.println(s0+s1); 31 32 List<String> l2 = dl.getList02(); 33 //取值的时候不需要转化 34 String s3 = l2.get(0); 35 String s4 = l2.get(1); 36 System.out.println(s3+s4); 37 } 38 }
泛型中的类型擦除
java中实质是不存在泛型类型对象的,JVM也根本不支持泛型类型,泛型类在经过JVM编译后生成的.class文件实为原始类型,泛型类型参数列表被去掉,JVM用类型参数的限定类型对类型参数进行替换;
因为类型擦除,所以:
不能用类型参数替换基本类型;
运行时的类型检查只检查泛型类的原始类型;
不能抛出也不能捕获泛型类的对象;
不能声明参数化类型的数组;
不能实例化未制定泛型类型的对象;
不能在静态域或者静态方法中引用类型变量;
泛型方法与原始方法的同名冲突;
1 import java.util.LinkedList; 2 import java.util.List; 3 4 5 public class Tset { 6 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 List l1 = new LinkedList(); 10 List<String> l2 = new LinkedList<String>(); 11 List<StringBuilder> l3 = new LinkedList<StringBuilder>(); 12 if(l1.getClass()==l2.getClass()){ 13 System.out.println("l1与l2类型相同"); 14 System.out.println("l1类型为"+l1.getClass().toString()); 15 System.out.println("l2类型为"+l2.getClass().toString()); 16 } 17 if(l1.getClass()==l3.getClass()){ 18 System.out.println("l1与l3类型相同"); 19 System.out.println("l1类型为"+l1.getClass().toString()); 20 System.out.println("l3类型为"+l3.getClass().toString()); 21 } 22 if(l2.getClass()==l3.getClass()){ 23 System.out.println("l2与l3类型相同"); 24 System.out.println("l2类型为"+l2.getClass().toString()); 25 System.out.println("l3类型为"+l3.getClass().toString()); 26 } 27 28 } 29 30 }
泛型与参数类型
泛型是基于类本身的,而不是基于参数类型,即存在继承关系的两个泛型类对象并不兼容;
1 List<Number> list = new LinkedList<Number>(); 2 List<Byte> list2 = new LinkedList<Byte>(); 3 list = list2;//错误!
使用类型通配符<?>可以使泛型无边界,使用extends<? extends 父类>或super<? super 父类>可以限定泛型的类型;
1 public void printList(List<?> list);//接收任何参数类型; 2 public void printList(List<? extends Number> list);//接收Number或Number子类型; 3 public void printList(List<? super Number> list);//接收Number或Number父类型;