泛型
-
泛型的意义:
a:可以对类型进行自动检查。 并不是替换,只是编译期间进行检查。
b:自动对类型进行转换。 -
泛型到底是怎么编译的?
类型的擦除机制:》向上擦除》Object(最高到)
在编译器编译期间,把泛型全部擦除为object类型。 -
用jmap命令查看内存泄漏:javac 》Javap -c jmap jps====>查看java进程号
jmap -histo:live 进程号> e:\log.txt
start e; -
泛型的上界:
< T extends Comparable< T > > -
泛型的坑:
1:不能new 泛型类型的数组 new T[]
2:不能new泛型类型的对象 T obj=new T()
3;不能new泛型类型的对象数组
Object[] obj=new GenericStack< Integer>[10];
obj[0]=“sadh”
obj[1]=Integer(10);
4: 不能用简单类型作为泛型类型的参数 //但是简单类型对应包装类可以自动装包的可以直接写简单类型;例如:需要一个Integer类型的,可以直接传int 类型的 因为int类型直接装包为Integer
5:GenericStack< 记得加引用类型的参数> genericStack3=new GenericStack< 记得加引用类型的参数>(); //后面的占位符可以不用写但是一般都要求写。
一定记得加< 泛型类型的参数>,否则就默认为Object。
6:在static方法中,不能使用泛型类型的参数,因为:static方法不依赖对象,如果不依赖对象,静态方法就不知道这个T是什么类型,那么编译的时候,拿什么去进行类型检查
static方法使用泛型,如果没有返回值,那占位符就放在void之前,如果有返回值,那就放在返回值T 之前
public static <T extends Comparable<T>> T findMaxVal(ArrayList<T> list){
//<T(T的上界为Comparaable) extends Comparable<T>> T
T max=list.get(0);
for(int i=0;i<list.size();i++){
if(max.compareTo(list.get(i))<0){
max=list.get(i);
}
}
return max;
}
通配符
- 也是运用擦除机制 ==》到object
- 通配符的上界:主要用于写入,一般用于库的开发 <? extends E> 可以接受E类型或者他的子类。
- 通配符的下界:主要用来读取
< ? super E> 可以接受E类型或者他的父类型。
import java.util.ArrayList;
/**
* @Created with IntelliJ IDEA
* @Description:
* @Package: PACKAGE_NAME
* @User: FLy
* @Date: 2018/11/19
* @Time: 16:37
*/
class GenericAlg{
public static <T extends Comparable<T>> T findMaxVal(ArrayList<T> list){
//<T(T的上界为Comparaable) extends Comparable<T>> T
T max=list.get(0);
for(int i=0;i<list.size();i++){
if(max.compareTo(list.get(i))<0){
max=list.get(i);
}
}
return max;
}
public static <T extends Comparable<? super T> > T findMaxVal2(ArrayList<T> list){
//<T(T的上界是Comparable,可以是它和他的子类) extends Comparable<? super T (通配符(?)的下界是T,可以是T 和他的父类)> > T(返回值类型为T)
T max=list.get(0);
for(int i=0;i<list.size();i++){
if(max.compareTo(list.get(i))<0){
max=list.get(i);
}
}
return max;
}
}
class Person implements Comparable<Person>{
private String name;
public Person(String name){
this.name=name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Person o) {
return this.name.compareTo(o.name);
}
}
class Student extends Person {
private int age;
public Student(String name,int age){
super(name);
this.age=age;
}
}
public class Generic {
public static void main(String args []){
ArrayList<Person>arrayList=new ArrayList<Person>();
arrayList.add(new Person("hehouzi"));
arrayList.add(new Person("zhouzelin"));
System.out.println(GenericAlg.findMaxVal(arrayList));//(GenericAlg.<Person>findMaxVal(arrayList))
//T会通过实参的类型推演出泛型的类型。
ArrayList<Student> arrayList1=new ArrayList<Student>();//后面的这个占位符可以写
arrayList1.add(new Student("haha",52)); // 也可以不写,但一般建议写
arrayList1.add(new Student("heihei",88));
System.out.println(GenericAlg.findMaxVal2(arrayList1));
}
}
注意:
//这些不可以构成继承关系
Integer ArratList<Integer>
Number ArrayList<Number>
Object ArrayList<Object>