泛型的概念
在编写集合相关代码时在eclipse里面总有一些黄色警告,在不使用注解的情况下,使用泛型之后,就不会有这些黄色警告了。
通过API可以看到Collection,List,ArrayList,这几个类里面都有,这个就是泛型,里面的E可以是任何引用数据类型,使用泛型指明了数据类型之后,这个集合里面只能存储这种数据类型的对象。
不使用泛型时,要进行多次类型强制转换
package com.monkey1024.generic;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.monkey1024.bean.Person;
/**
* 不使用泛型的缺点
*
*/
public class GenericTest01 {
public static void main(String[] args) {
List list = new ArrayList();
//如果不使用泛型可以像list中存放不同的数据类型
list.add("monkey");
list.add(1024);
list.add(new Person("刘德华", 51));
Iterator iter = list.iterator();
while(iter.hasNext()){
//只能做大量的类型判断
Object obj = iter.next();
if(obj instanceof String){
String s = (String)obj;
}
if(obj instanceof Integer){
Integer i = (Integer)obj;
}
if(obj instanceof Person){
Person p = (Person)obj;
}
}
}
}
使用泛型之后:
package com.monkey1024.generic;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.monkey1024.bean.Person;
/**
* 使用泛型
*
*/
public class GenericTest02 {
public static void main(String[] args) {
//前后数据类型保持一致
List<Person> list = new ArrayList<Person>();
//jdk7加入的菱形泛型
List<Person> list7 = new ArrayList<>();
//下面代码编译报错
// list.add("monkey");
// list.add(1024);
list.add(new Person("刘德华", 51));
Iterator<Person> iter = list.iterator();
while(iter.hasNext()){
Person p = (Person)iter.next();
}
}
}
泛型的优点
可以统一集合中的数据类型,提高安全性
可以减少强制类型转换
自定义泛型
通过JDK的源码可以看到,泛型一般写的都是或者,里面的T和E就是表示使用者指定的类型。可以自己定义一个使用泛型的类
package com.monkey1024.generic;
/**
* 自定义泛型
* 类上面使用泛型
* @param <T>
*/
public class Value<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
//方法的泛型最好与类一致,如果不一致需要在方法上面声明泛型
public<M> void show(M m){
System.out.println(m);
}
}
泛型通配符
在实际工作当中,有可能通过调用某个方法来接受一个返回值List的数据,这样就不太好确定返回值中的数据类型,这样可以使用泛型通配符<?>
List<?> list = new ArrayList
使用泛型通配符限定子类或者父类
? extends E
向下限定,E及其子类,可以存储当前类型的子类
? super E
向上限定,E及其父类,可以存储当前类型的父类
定义一个Student类继承Person
package com.monkey1024.bean;
public class Student extends Person {
public Student() {
super();
}
public Student(String name, int age) {
super(name, age);
}
}
在List中方法addAll是限定了子类(? extends E),定义测试类:
package com.monkey1024.generic;
import java.util.ArrayList;
import java.util.List;
/**
* ? extends E 向下限定,E及其子类,可以存储当前类型的子类
* ? super E 向上限定,E及其父类,可以存储当前类型的父类
*
*/
public class GenericTest03 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("张三", 23));
personList.add(new Person("李四", 24));
personList.add(new Person("王五", 25));
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("赵六", 26));
studentList.add(new Student("周七", 27));
//因为studentList中存放的Student是Person类的子类,所以可以将studentList放入personList中
personList.addAll(studentList);
System.out.println(personList);
}
}