泛型<>:jdk1.5出现的安全机制。
一、好处:
1,将运行时期的问题ClassCastException转到了编译时期。
2,避免了强制转换的麻烦。
二、<>特点
1,什么时候用?
当操作的引用数据类型不确定的时候。就使用<>。将要操作的引用数据类型传入即可.其实<>就是一个用于接收具体引用数据类型的参数范围。
2,在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型 。
3,泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。
4,运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除,因为为了兼容运行的类加载器。
5,泛型的补偿:在运行时,通过获取元素的类型进行转换动作,不用使用者再强制转换了。
6,泛型的通配符:? 未知类型。
7,泛型的限定
? extends E: 接收E类型或者E的子类型对象(上限。一般存储对象的时候用。比如 添加元素 addAll. ? super E: 接收E类型或者E的父类型对象(下限)。一般取出对象的时候用。比如比较器。
三、示例
Person类
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int compareTo(Person p){
int temp = this.age - p.age;
return temp==0?this.name.compareTo(p.name):temp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person:"+getName()+":"+getAge();
}
}
测试代码:
public class GenericDemo2 {
/**
* @param args
*/
public static void main(String[] args) {
TreeSet<Person> ts = new TreeSet<Person>(new ComparatorByName());
ts.add(new Person("lisi8",21));
ts.add(new Person("lisi3",23));
ts.add(new Person("lisi",21));
ts.add(new Person("lis0",20));
Iterator<Person> it = ts.iterator();
while(it.hasNext()){
Person p = it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
如果存储非泛型定义的类型,编译时会出现错误提示:
四、泛型类
1,自定义泛型类
public class Tool<QQ>{
private QQ q;
public QQ getObject() {
return q;
}
public void setObject(QQ object) {
this.q = object;
}
}
2,泛型方法(非静态方法)
public class Tool<QQ>{
public <W> void show(W str){
System.out.println("show : "+str.toString());
}
public void print(QQ str){
System.out.println("print : "+str);
}
}
3,静态泛型方法
public static <Y> void method(Y obj){
System.out.println("method:"+obj);
}
五、泛型接口
1,接口的定义
interface Inter<T>{
public void show(T t);
}
2,接口的实现
class InterImpl implements Inter<String>{
public void show(String str){
System.out.println("show :"+str);
}
}
3,子类接口
class InterImpl2<Q> implements Inter<Q>{
public void show(Q q){
System.out.println("show :"+q);
}
}
六、泛型的限定
1,上限:? extends E:接收E类型或者E的子类型对象
代码示例:
public class GenericAdvanceDemo2 {
public static void main(String[] args) {
ArrayList<Worker> al = new ArrayList<Worker>();
al.add(new Worker("abc",30));
al.add(new Worker("abc4",34));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("stu1",11));
al2.add(new Student("stu2",22));
ArrayList<String> al3 = new ArrayList<String>();
al3.add("stu3331");
al3.add("stu33332");
printCollection(al2);
printCollection(al);
}
public static void printCollection(Collection<? extends Person> al) {
Iterator<? extends Person> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
运行结果:
2,下限: ? super E :接收E类型或者E的父类型
代码示例:
public class GenericAdvanceDemo2 {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("abc",30));
al.add(new Person("abc4",34));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("stu1",11));
al2.add(new Student("stu2",22));
ArrayList<String> al3 = new ArrayList<String>();
al3.add("stu3331");
al3.add("stu33332");
printCollection(al2);
printCollection(al);
}
public static void printCollection(Collection<? super Student> al){
Iterator<? super Student> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
运行结果:
3,上限的体现
一般在存储元素的时候都是用上限,因为这样取出都是按照上限类型来运算的。不会出现类型安全隐患
4,下限的体现
通常对集合中的元素进行取出操作时,可以是用下限
七、通配符
< ? >未知类型