首页 > 代码库 > 【JAVA之泛型】
【JAVA之泛型】
一、引例。
1.引例。
假设现在有一个ArrayList的容器,如果不使用泛型约束,则可以向容器中加入各种类型的对象,但是如果取出来的时候只是用一种类型的转换则肯定会抛出ClassCastException异常。
1 package p04.GenerateTypeDemo.Demo01; 2 3 import java.util.ArrayList; 4 import java.util.ListIterator; 5 6 public class Demo01 { 7 public static void main(String args[]) 8 { 9 ArrayList al=new ArrayList();10 al.add("abc1");11 al.add("abc2");12 al.add(1);13 al.add(2);14 ListIterator li=al.listIterator();15 while(li.hasNext())16 {17 String str=(String)li.next();18 System.out.println(str);19 }20 }21 22 }
虽然这个程序在Eclipse中编译时并没有报错,但是运行的时候则会产生ClassCastException异常,这样就产生了潜在的风险。虽然Eclipse没有报错,但是它会使用黄色小叹号提示程序员这样做有潜在的风险。该怎么保证在编译时期就确定是否有风险呢?泛型在JDK1.5之后就为此而产生了。
泛型使用<>来表示,<>里面天上泛型的类型。这样容器就只能接收指定类型的对象了。
更改代码:
1 package p04.GenerateTypeDemo.Demo01; 2 3 import java.util.ArrayList; 4 import java.util.ListIterator; 5 6 public class Demo01 { 7 public static void main(String args[]) 8 { 9 ArrayList<String>al=new ArrayList<String>();10 al.add("abc1");11 al.add("abc2");12 al.add(1);13 al.add(2);14 ListIterator<String> li=al.listIterator();15 while(li.hasNext())16 {17 String str=(String)li.next();18 System.out.println(str);19 }20 }21 22 }
这个代码相对上一个代码来说只是加入了泛型,其余均没有变化,但是在Eclipse中还没有运行就已经报错了。
这就是使用泛型的最大好处。同时,也应当注意,使用泛型之后,迭代器也要使用泛型来定义将要迭代的元素类型,一旦这样做之后,取出元素的时候就不需要做强转动作了。
1 package p04.GenerateTypeDemo.Demo01; 2 3 import java.util.ArrayList; 4 import java.util.ListIterator; 5 6 public class Demo01 { 7 public static void main(String args[]) 8 { 9 ArrayList<String>al=new ArrayList<String>();10 al.add("abc1");11 al.add("abc2");12 al.add("abc3");13 al.add("abc4");14 ListIterator<String> li=al.listIterator();15 while(li.hasNext())16 {17 String str=li.next();18 System.out.println(str);19 }20 }21 22 }
2.总结:
泛型是什么:泛型是JDK1.5之后出现的新特性。
使用泛型的目的:为了提高安全机制。(JDK升级几乎只为了三个目的:提高效率、简化书写、提高安全性)
使用泛型的好处:
1.将运行时期的问题ClasscastException转到了编译时期。
2.避免了强制转换的麻烦。
解惑:<>和E
<>是什么?
就像方法中使用()来界定参数范围,泛型使用<>界定要传入的参数类型。
<>什么时候用?
当操作的引用数据类型不确定的时候使用。
E是什么?
E代表一个参数,为Element的简写,不使用小写的原因就是E代表的参数类型只限于引用型数据类型,而不包括基本数据类型。
3.泛型的擦除和补偿。
擦除:虽然程序员在写代码的时候使用了泛型,但是在JAVA编译器生成Class文件的时候,会将泛型去掉,生成的Class文件中并没有泛型。这称为反省的擦除。
补偿:擦除的目的是为了兼容低版本jre,但是泛型技术中不使用强制转换却没有办法使得低版本支持,所以编译器略作调整,它将自动获取对象类型(使用getClass方法)并完成隐式的强转动作。这就是泛型的补偿。
二、泛型类、泛型方法、泛型接口。
1.泛型在TreeSet集合中的使用。
TreeSet在集合框架中是比较复杂的一个容器,所以使用它作为演示容器。
【JAVA之泛型】