泛型能更早的发现错误,如类型转换错误,通常在运行期才会发现,如果使用泛型,那么在编译期将会发现,通常错误发现的越早,越容易调试,越容易减少成本
1、为什么使用泛型
import java.util.*;public class GenericTest01 {public static void main(String[] args) {List l = new ArrayList();l.add(1);l.add(2);l.add(3);for (Iterator iter=l.iterator(); iter.hasNext();) {//出现了java.lang.ClassCastException异常//这种转型错误时运行期发现了//错误发现的越早越好,最好在编译器能发现类似的错误//如果想在编译器发现类似的错误,必须使用泛型String s = (String)iter.next();System.out.println(s);}}}
2、使用泛型解决示例一
import java.util.*;public class GenericTest02 {public static void main(String[] args) {List<Integer> l = new ArrayList<Integer>();l.add(1);l.add(2);l.add(3);//不能将abc放到集合中,因为使用泛型,在编译器就可以返现错误//l.add("abc");for (Iterator<Integer> iter=l.iterator(); iter.hasNext();) {//因为使用泛型,在编译器就可以发现错误//String s = (String)iter.next();//使用泛型可以不用进行强制转换//Integer s = (Integer)iter.next();//可以直接取得相应的元素,使用泛型返回的是真正的类型Integer s = iter.next();System.out.println(s);}}}
3、采用泛型来改善自定义比较器
import java.util.*;public class GenericTest03 {public static void main(String[] args) {Person p1 = new Person();p1.name = "张三";p1.age = 20;Person p3 = new Person();p3.name = "张三";p3.age = 40;Person p2 = new Person();p2.name = "李四";p2.age = 30;Set<Person> set = new TreeSet<Person>();set.add(p1);set.add(p2);set.add(p3);for (Iterator<Person> iter=set.iterator(); iter.hasNext();) {Person p = iter.next();System.out.println("name=" + p.name + ", age=" + p.age);}}}class Person implements Comparable<Person> {String name;int age;//使用了泛型类似的instanceof就不用再写了public int compareTo(Person o) {return (this.age - o.age);}}
4、采用泛型改造Map
import java.util.*;public class GenericTest04 {public static void main(String[] args) {IdCard idCard1 = new IdCard();idCard1.cardNo = 223243244243243L;Person person1 = new Person();person1.name = "张三";IdCard idCard2 = new IdCard();idCard2.cardNo = 223243244244343L;Person person2 = new Person();person2.name = "李四";IdCard idCard3 = new IdCard();idCard3.cardNo = 223243244243243L;Person person3 = new Person();person3.name = "张三";Map<IdCard, Person> map = new HashMap<IdCard, Person>();map.put(idCard1, person1);map.put(idCard2, person2);map.put(idCard3, person3);//不能编译//map.put("1001", "王五");for (Iterator<Map.Entry<IdCard, Person>> iter=map.entrySet().iterator(); iter.hasNext();) {/*Map.Entry entry = (Map.Entry)iter.next();IdCard idCard = (IdCard)entry.getKey();Person person = (Person)entry.getValue();*/Map.Entry<IdCard, Person> entry = iter.next();//不能转换//String s = (String)entry.getKey();IdCard idCard = entry.getKey();Person person = entry.getValue();System.out.println(idCard.cardNo + ", " + person.name);}}}class IdCard {long cardNo;//.........public boolean equals(Object obj) {if (obj == this) {return true;}if (obj instanceof IdCard) {IdCard idCard = (IdCard)obj;if (this.cardNo == idCard.cardNo) {return true;}}return false;}public int hashCode() {return new Long(cardNo).hashCode();}}class Person {String name;}
5、自定义泛型
import java.util.*;public class GenericTest05 {private Object obj;public void setObj(Object obj) {this.obj = obj;}public Object getObj() {return obj;}public static void main(String[] args) {GenericTest05 g = new GenericTest05();g.setObj("abcd");//抛出java.lang.ClassCastException错误//因为不知道Object到底是什么类型Integer i = (Integer)g.getObj();}}
【示例代码】,自定泛型
import java.util.*;public class GenericTest06<T> {private T obj;public void setObj(T obj) {this.obj = obj;}public T getObj() {return obj;}public static void main(String[] args) {GenericTest06<String> g = new GenericTest06<String>();g.setObj("abcd");//不能设置int类型//因为使用泛型规定只能设置为String类型//g.setObj(123);//不能转换,因为String类型//Integer i = (Integer)g.getObj();//使用泛型后不用再进行强制转换了//它返回的就是真正的类型String s = g.getObj();}}
【示例代码】,修改泛型标识
import java.util.*;//泛型的标示符没有限制,只有符合java的标示符命名规范即可//最好和JDK的泛型标识一样public class GenericTest07<AAA> {private AAA obj;public void setObj(AAA obj) {this.obj = obj;}public AAA getObj() {return obj;}public static void main(String[] args) {GenericTest07<String> g = new GenericTest07<String>();g.setObj("abcd");String s = g.getObj();}}
