泛型:
jdk1.5出现的安全机制。
好处:
1,将运行时期的问题ClassCastException转到了编译时期。
2,避免了强制转换的麻烦。
<>:什么时候用?当操作的引用数据类型不确定的时候。就使用<>。将要操作的引用数据类型传入即可.
其实<>就是一个用于接收具体引用数据类型的参数范围。
在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型 。
泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。
运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。
为什么擦除呢?因为为了兼容运行的类加载器。
泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者在强制转换了。
- 将泛型定义在类上
public class Tool<QQ>{
private QQ q;
public QQ getObject() {
return q;
}
public void setObject(QQ object) {
this.q = object;
}
}
- 将泛型定义在方法上
/**
* 将泛型定义在方法上。
* @param str
*/
public <W> void show(W str){
System.out.println("show : "+str.toString());
}
public void print(QQ str){
System.out.println("print : "+str);
}
注意:
1.泛型必须写在返回类型修饰符前。
2.当方法静态时,不能访问类上定义的泛型。如果静态方法使用泛型,只能将泛型定义在方法上。
/**
* 当方法静态时,不能访问类上定义的泛型。如果静态方法使用泛型,
* 只能将泛型定义在方法上。
* @param obj
*/
public static <Y> void method(Y obj){
System.out.println("method:"+obj);
}
- 泛型接口,将泛型定义在接口上,以下两种实现接口的方式都行,只要看什么时候明确了类型
interface Inter<T>{
public void show(T t);
}
class InterImpl2<Q> implements Inter<Q>{
public void show(Q q){
System.out.println("show :"+q);
}
}
class InterImpl implements Inter<String>{
public void show(String str){
System.out.println("show :"+str);
}
}
泛型的通配符:? 未知类型。
示例代码:
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("abc");
al.add("hehe");
ArrayList<Integer> al2 = new ArrayList<Integer>();
al2.add(5);
al2.add(67);
printCollection(al);
printCollection(al2);
}
/**
* 迭代并打印集合中元素。
* @param al
*/
public static void printCollection(Collection<?> al) {
Iterator<?> it = al.iterator();
while(it.hasNext()){
// T str = it.next();
// System.out.println(str);
System.out.println(it.next().toString());
}
}
泛型的限定:
? extends E: 接收E类型或者E的子类型对象。上限
一般存储对象的时候用。因为这样取出都是按照上限类型来运算的。不会出现类型安全隐患。 比如 添加元素 addAll.
class MyCollection<E>{
public void add(E e){
}
public void addAll(MyCollection<? extends E> e){
}
}
public static void printCollection(Collection<? extends Person> al) {//Collection<Dog> al = new ArrayList<Dog>()
Iterator<? extends Person> it = al.iterator();
while(it.hasNext()){
// T str = it.next();
// System.out.println(str);
// System.out.println(it.next().toString());
Person p = it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}*/
? super E: 接收E类型或者E的父类型对象。 下限。
一般取出对象的时候用。比如比较器。
class TreeSet<Worker>
{
Tree(Comparator<? super Worker> comp);
}
public static void printCollection(Collection<? super Student> al){
Iterator<? super Student> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}