泛型能更早的发现错误,如类型转换错误,通常在运行期才会发现,如果使用泛型,那么在编译期将会发现,通常错误发现的越早,越容易调试,越容易减少成本

1、为什么使用泛型

  1. import java.util.*;
  2. public class GenericTest01 {
  3. public static void main(String[] args) {
  4. List l = new ArrayList();
  5. l.add(1);
  6. l.add(2);
  7. l.add(3);
  8. for (Iterator iter=l.iterator(); iter.hasNext();) {
  9. //出现了java.lang.ClassCastException异常
  10. //这种转型错误时运行期发现了
  11. //错误发现的越早越好,最好在编译器能发现类似的错误
  12. //如果想在编译器发现类似的错误,必须使用泛型
  13. String s = (String)iter.next();
  14. System.out.println(s);
  15. }
  16. }
  17. }

2、使用泛型解决示例一

  1. import java.util.*;
  2. public class GenericTest02 {
  3. public static void main(String[] args) {
  4. List<Integer> l = new ArrayList<Integer>();
  5. l.add(1);
  6. l.add(2);
  7. l.add(3);
  8. //不能将abc放到集合中,因为使用泛型,在编译器就可以返现错误
  9. //l.add("abc");
  10. for (Iterator<Integer> iter=l.iterator(); iter.hasNext();) {
  11. //因为使用泛型,在编译器就可以发现错误
  12. //String s = (String)iter.next();
  13. //使用泛型可以不用进行强制转换
  14. //Integer s = (Integer)iter.next();
  15. //可以直接取得相应的元素,使用泛型返回的是真正的类型
  16. Integer s = iter.next();
  17. System.out.println(s);
  18. }
  19. }
  20. }

3、采用泛型来改善自定义比较器

  1. import java.util.*;
  2. public class GenericTest03 {
  3. public static void main(String[] args) {
  4. Person p1 = new Person();
  5. p1.name = "张三";
  6. p1.age = 20;
  7. Person p3 = new Person();
  8. p3.name = "张三";
  9. p3.age = 40;
  10. Person p2 = new Person();
  11. p2.name = "李四";
  12. p2.age = 30;
  13. Set<Person> set = new TreeSet<Person>();
  14. set.add(p1);
  15. set.add(p2);
  16. set.add(p3);
  17. for (Iterator<Person> iter=set.iterator(); iter.hasNext();) {
  18. Person p = iter.next();
  19. System.out.println("name=" + p.name + ", age=" + p.age);
  20. }
  21. }
  22. }
  23. class Person implements Comparable<Person> {
  24. String name;
  25. int age;
  26. //使用了泛型类似的instanceof就不用再写了
  27. public int compareTo(Person o) {
  28. return (this.age - o.age);
  29. }
  30. }

4、采用泛型改造Map

  1. import java.util.*;
  2. public class GenericTest04 {
  3. public static void main(String[] args) {
  4. IdCard idCard1 = new IdCard();
  5. idCard1.cardNo = 223243244243243L;
  6. Person person1 = new Person();
  7. person1.name = "张三";
  8. IdCard idCard2 = new IdCard();
  9. idCard2.cardNo = 223243244244343L;
  10. Person person2 = new Person();
  11. person2.name = "李四";
  12. IdCard idCard3 = new IdCard();
  13. idCard3.cardNo = 223243244243243L;
  14. Person person3 = new Person();
  15. person3.name = "张三";
  16. Map<IdCard, Person> map = new HashMap<IdCard, Person>();
  17. map.put(idCard1, person1);
  18. map.put(idCard2, person2);
  19. map.put(idCard3, person3);
  20. //不能编译
  21. //map.put("1001", "王五");
  22. for (Iterator<Map.Entry<IdCard, Person>> iter=map.entrySet().iterator(); iter.hasNext();) {
  23. /*
  24. Map.Entry entry = (Map.Entry)iter.next();
  25. IdCard idCard = (IdCard)entry.getKey();
  26. Person person = (Person)entry.getValue();
  27. */
  28. Map.Entry<IdCard, Person> entry = iter.next();
  29. //不能转换
  30. //String s = (String)entry.getKey();
  31. IdCard idCard = entry.getKey();
  32. Person person = entry.getValue();
  33. System.out.println(idCard.cardNo + ", " + person.name);
  34. }
  35. }
  36. }
  37. class IdCard {
  38. long cardNo;
  39. //.........
  40. public boolean equals(Object obj) {
  41. if (obj == this) {
  42. return true;
  43. }
  44. if (obj instanceof IdCard) {
  45. IdCard idCard = (IdCard)obj;
  46. if (this.cardNo == idCard.cardNo) {
  47. return true;
  48. }
  49. }
  50. return false;
  51. }
  52. public int hashCode() {
  53. return new Long(cardNo).hashCode();
  54. }
  55. }
  56. class Person {
  57. String name;
  58. }

5、自定义泛型

  1. import java.util.*;
  2. public class GenericTest05 {
  3. private Object obj;
  4. public void setObj(Object obj) {
  5. this.obj = obj;
  6. }
  7. public Object getObj() {
  8. return obj;
  9. }
  10. public static void main(String[] args) {
  11. GenericTest05 g = new GenericTest05();
  12. g.setObj("abcd");
  13. //抛出java.lang.ClassCastException错误
  14. //因为不知道Object到底是什么类型
  15. Integer i = (Integer)g.getObj();
  16. }
  17. }

【示例代码】,自定泛型

  1. import java.util.*;
  2. public class GenericTest06<T> {
  3. private T obj;
  4. public void setObj(T obj) {
  5. this.obj = obj;
  6. }
  7. public T getObj() {
  8. return obj;
  9. }
  10. public static void main(String[] args) {
  11. GenericTest06<String> g = new GenericTest06<String>();
  12. g.setObj("abcd");
  13. //不能设置int类型
  14. //因为使用泛型规定只能设置为String类型
  15. //g.setObj(123);
  16. //不能转换,因为String类型
  17. //Integer i = (Integer)g.getObj();
  18. //使用泛型后不用再进行强制转换了
  19. //它返回的就是真正的类型
  20. String s = g.getObj();
  21. }
  22. }

【示例代码】,修改泛型标识

  1. import java.util.*;
  2. //泛型的标示符没有限制,只有符合java的标示符命名规范即可
  3. //最好和JDK的泛型标识一样
  4. public class GenericTest07<AAA> {
  5. private AAA obj;
  6. public void setObj(AAA obj) {
  7. this.obj = obj;
  8. }
  9. public AAA getObj() {
  10. return obj;
  11. }
  12. public static void main(String[] args) {
  13. GenericTest07<String> g = new GenericTest07<String>();
  14. g.setObj("abcd");
  15. String s = g.getObj();
  16. }
  17. }