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