1.简介
(1).概念
Java允许在定义方法、类和接口时不指定具体的数据类型,而是在范型方法被调用、范型类被实例化、范型接口被实现时再指定具体数据类型,这样便可以让数据类型变得参数化。
(2).范型擦除和补偿
泛型技术是给编译器使用的,编译器在检查完后,生成的.class文件中不带泛型,原因是泛型是 JDK5.0以后出现的技术,类加载器不能识别,这叫做擦除。在运行过程中,又带有泛型,原因是类加载器获取.class字节码文件,根据运行时类中的数据类型,进行类强制转换,这叫做泛型补偿。
(3).范型字母含义
- E:Element
- T:Type
- K:Key
- V:Value
- N:Number
(4).演示案例
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//get和set方法
}
public class Student extends Person {
public Student(String name, int age) {
super(name, age);
}
@Override
public String toString() {
return "Student{}";
}
}
public class Worker extends Person {
public Worker(String name, int age) {
super(name, age);
}
@Override
public String toString() {
return "Worker{}";
}
}
2.泛型类
public class Tool<T>{
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
public class GenericDemo {
public static void main(String[] args) {
Tool<Student> tool = new Tool<>();
tool.setT(new Student("steven",30));
//报错
tool.setT(new Worker("steven",30));
System.out.println(tool.getT());
}
}
Student{}
3.泛型方法
public class Tool<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public static <E> void printElement(E[] inputArray) {
for (int i = 0; i < inputArray.length; i++) {
System.out.println(inputArray[i]);
}
System.out.println();
}
}
public class GenericDemo {
public static void main(String[] args) {
String [] stringArray = new String[]{"book","fruit","sport"};
Integer [] interArray = new Integer[]{123,12345,123456};
Tool.printElement(stringArray);
Tool.printElement(interArray);
}
}
book
fruit
sport
123
1234
12345
getT()不是泛型方法,printElement是泛型方法,主要区别在于泛型方法有<>修饰。
4.泛型接口
public interface IGeneric<T> {
T getT();
}
class GenericStudentImpl implements IGeneric<Student>{
@Override
public Student getT() {
return new Student("steven",30);
}
public static void main(String[] args) {
GenericStudentImpl genericStudent = new GenericStudentImpl();
Student student = genericStudent.getT();
System.out.println(student);
}
}
Student{}
5.泛型边界
(1).上限extends
public class GenericDemo {
public static void main(String[] args) {
List<Person> personList = new LinkedList<Person>();
personList.add(new Person("steven", 27));
personList.add(new Person("sherry", 20));
print(personList);
System.out.println();
List<Student> studentList = new LinkedList<>();
studentList.add(new Student("owen", 22));
studentList.add(new Student("mike", 25));
print(studentList);
System.out.println();
List<Worker> workerList = new LinkedList<>();
workerList.add(new Worker("jan", 23));
workerList.add(new Worker("tom", 24));
print(workerList);
}
private static void print(Collection<? extends Person> coll) {
Iterator<?> it = coll.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println("name:" + p.getName() + ",age:" + p.getAge());
}
}
}
name:steven,age:27
name:sherry,age:20
name:owen,age:22
name:mike,age:25
name:jan,age:23
name:tom,age:24
(2).下限super
public class GenericDemo {
public static void main(String[] args) {
//编译不通过
//List<Person> personList = new LinkedList<Person>();
//personList.add(new Person("steven", 27));
//personList.add(new Person("sherry", 20));
//print(personList);
//System.out.println();
List<Student> studentList = new LinkedList<>();
studentList.add(new Student("owen", 22));
studentList.add(new Student("mike", 25));
print(studentList);
System.out.println();
//编译不通过
//List<Worker> workerList = new LinkedList<>();
//workerList.add(new Worker("jan", 23));
//workerList.add(new Worker("tom", 24));
//print(workerList);
}
private static void print(Collection<? extends Student> coll) {
Iterator<?> it = coll.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println("name:" + p.getName() + ",age:" + p.getAge());
}
}
}
name:owen,age:22
name:mike,age:25