泛型:
jdk1.5出现的安全机制
好处:
1.将运行时期的问题ClassCastException转到了编译时期。
2.避免了强制转换的麻烦。
<>:
什么时候用?
当操作的引用数据类型不确定的时候,就使用<>。将要操作的引用数据类型传入即可。
其实<>就是一个用于接收具体引用数据类型的参数范围。
在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型。
泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。
运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。
为什么要擦除呢? 为了兼容运行的类加载器。
泛型的补偿: 在运行时,通过获取元素的类型进行转换动作。不用 使用者 在强制转换了。
泛型的通配符: ? 未知类型
泛型的限定:
? extends E:接受E类型或E的子类型对象。上限一般存储对象的时候用。比如,添加元素 addAll boolean addAll(<? extends E> c)
? super E :接受E类型或E的父类型对象。下限,一般取出对象的时候用。比如比较器。 TreeSet(Comparator<? super E> comparator)
泛型例子:
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 4 public class GenericDemo { 5 6 public static void main(String[] args) { 7 ArrayList<String> al = new ArrayList<String>(); //强制转化 8 9 al.add("abc"); 10 al.add("hahah"); 11 // al.add(123); //会报错 12 13 Iterator<String> it = al.iterator(); //强制转化 14 15 while (it.hasNext()) 16 { 17 String str = it.next(); //不用强制转化了 18 System.out.println(str); 19 } 20 21 } 22 23 }
Comparator,Comparable的泛型
1 package p2; 2 3 public class Person implements Comparable<Person> { 4 private String name; 5 private int age; 6 7 public Person(){ 8 super(); 9 } 10 11 public Person(String name, int age) 12 { 13 super(); 14 this.name = name; 15 this.age = age; 16 } 17 18 @Override 19 public int compareTo(Person o) { 20 // Person p = (Person)obj; //不用强制转化了 21 int temp = this.age - o.age; 22 23 return temp==0?this.name.compareTo(o.name):temp; 24 } 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public int getAge() { 35 return age; 36 } 37 38 public void setAge(int age) { 39 this.age = age; 40 } 41 42 /* (非 Javadoc) 43 * @see java.lang.Object#hashCode() 44 */ 45 @Override 46 public int hashCode() { 47 final int prime = 31; 48 int result = 1; 49 result = prime * result + age; 50 result = prime * result + ((name == null) ? 0 : name.hashCode()); 51 return result; 52 } 53 54 /* (非 Javadoc) 55 * @see java.lang.Object#equals(java.lang.Object) 56 */ 57 @Override 58 public boolean equals(Object obj) { 59 if (this == obj) 60 return true; 61 if (obj == null) 62 return false; 63 if (getClass() != obj.getClass()) 64 return false; 65 Person other = (Person) obj; 66 if (age != other.age) 67 return false; 68 if (name == null) { 69 if (other.name != null) 70 return false; 71 } else if (!name.equals(other.name)) 72 return false; 73 return true; 74 } 75 76 /* (非 Javadoc) 77 * @see java.lang.Object#toString() 78 */ 79 @Override 80 public String toString() { 81 return "Person [name=" + name + ", age=" + age + "]"; 82 } 83 84 85 86 } 87 88 89 package p3; 90 91 import java.util.Comparator; 92 93 import p2.Person; 94 95 public class ComparatorByName implements Comparator<Person> { 96 97 @Override 98 public int compare(Person o1, Person o2) { 99 int temp = o1.getName().compareTo(o2.getName()); 100 101 return temp==0? o1.getAge()-o2.getAge() : temp; 102 } 103 104 105 } 106 107 import java.util.Iterator; 108 import java.util.TreeSet; 109 110 import p2.Person; 111 import p3.ComparatorByName; 112 113 public class GenericDemo2 { 114 115 public static void main(String[] args) { 116 TreeSet<Person> ts = new TreeSet<Person>(new ComparatorByName()); 117 118 ts.add(new Person("sfsf",21)); 119 ts.add(new Person("fdg",14)); 120 ts.add(new Person("erw",18)); 121 ts.add(new Person("iu",30)); 122 123 Iterator<Person> it = ts.iterator(); 124 125 while(it.hasNext()) 126 { 127 Person p = it.next(); 128 129 System.out.println(p); 130 } 131 132 } 133 134 }
类和方法上的泛型
1 public class Tool<QQ> { 2 private QQ q; 3 4 public QQ getObject() { 5 return q; 6 } 7 8 public void setObject(QQ object) { 9 this.q = object; 10 } 11 12 /* 13 * 将泛型定义在方法上 14 * 15 * */ 16 17 public <W> void show(W str) 18 { 19 System.out.println(str.toString()); 20 } 21 22 public void print(QQ str) 23 { 24 System.out.println(str); //如果写str.length(); 是错误的; 因为不知道泛型QQ究竟是什么具体类型,所以不能使用具体类型的方法。 25 //不过可以使用Object的方法 26 } 27 28 /* 29 * 当方法静态时,不能访问类上定义的泛型。 30 * 如果静态方法使用泛型,只能将泛型定义在方法上。 31 * 泛型一定要放在返回值类型的前面,修饰符的后面 32 * 33 * */ 34 public static <Y> void method(Y obj) 35 { 36 System.out.println(obj); 37 } 38 39 40 41 }