泛型:jdk1.5出现的安全机制。
好处:
1.将运行时期的问题ClassCastException转到了编译时期。
2.避免了强制转换的麻烦。
<>:什么时候使用?
当操作的引用数据类型不确定的时候,就使用<>.将要操作的引用数据类型传入即可,其实<>就是一个用于接收具体引用数据类型的参数范围。
在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型。
泛型技术是给编译器使用的技术,用于编译时确保类型的安全;但运行时会将泛型去掉,生成的class文件中是不带反省的,这个称为泛型的擦除。为什么擦除呢?因为为了兼容运行时的类加载器。
泛型的补偿:在运行时,通过获取元素的类型进行转换动作,不用使用者在使用时进行强制转换。
泛型.png
如下:存储不同类型的数据时,会出现错误,原因在于强制转换时,已经将类型转换成String类,存储int类型时当然会出错
package com.vv.generic;
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList al = new ArrayList();
al.add("sd");//public boolean add(Object obj)
al.add("sds");
al.add(4);//al.add(new Integer(4));
Iterator it = al.iterator();
while(it.hasNext()){
//必须加强制类型转换,因为add的是Object类
String str = (String) it.next();
System.out.println(str);
}
}
}
结果如下:
即类型转换出错
sd
sds
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.vv.generic.GenericDemo.main(GenericDemo.java:18)
为避免上述错误的出现,jdk1.5即出现泛型来改善此类情况,举例如下:
package com.vv.generic.demo;
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> al = new ArrayList();
al.add("sd");//public boolean add(Object obj)
al.add("sds");
// 赋予泛类型后,系统会自动检测添加的类型是否一致
// al.add(4);//al.add(new Integer(4));
Iterator it = al.iterator();
while(it.hasNext()){
//必须加强制类型转换,因为add的是Object类
String str = (String) it.next();
System.out.println(str);
}
}
}
泛型的举例,根据Person年龄排序:
测试类
package com.vv.generic.demo;
import java.util.Iterator;
import java.util.TreeSet;
import com.vv.bean.Person;
public class GenericDemo2 {
public static void main(String[] args) {
//注意在使用的时候就应该明确要装在的类型
TreeSet<Person> ts = new TreeSet<Person>();
ts.add(new Person("zhangsan",12));
ts.add(new Person("lisi",22));
ts.add(new Person("wangwu",32));
ts.add(new Person("zhangsana",12));
Iterator<Person> it = ts.iterator();
while(it.hasNext()){
Person p = it.next();
System.out.println(p.getName()+p.getAge());
}
}
}
Person类
即TreeSet排序方式一:在person类中实现comparable接口并覆盖CompareTo方法
泛型.png
package com.vv.bean;
public class Person implements Comparable<Person>{
private String name;
private int age;
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;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
/*
//当实现的是Comparable时
@Override
public int compareTo(Object o) {
Person p = (Person) o;
int temp = this.age - p.age;
return temp == 0 ? this.name.compareTo(p.name) : temp;
}
*/
//当实现的是Comparable<Person>时
@Override
public int compareTo(Person p) {
int temp = this.age - p.age;
return temp == 0 ? this.name.compareTo(p.name) : temp;
}
}
TreeSet排序方式二:实现comparator接口
package com.vv.comparator;
import java.util.Comparator;
import com.vv.bean.Person;
public class ComparatorByName implements Comparator<Person>{
@Override
public int compare(Person p1,Person p2) {
int temp = p1.getName().compareTo(p2.getName());
return temp == 0 ? p1.getAge() - p2.getAge() : temp;
}
}
同时测试类中创建对象时也应该做如下改变
TreeSet<Person> ts = new TreeSet<Person>(new ComparatorByName());
网友评论