泛型的概念
在声明方法时,有未知参数参与,这些数据的类型需要在方法调用时才能确定
所以JDK1.5引入了泛型的概念,用来代表未知的通用的类型
示例
class Circle{
private double radius;
public Circle(double radius) {
super();
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public String toString() {
return "Circle [radius=" + radius + "]";
}
}
class CircleComparator implements Comparator<Circle>{
@Override
public int compare(Circle o1, Circle o2) {
//不再需要强制类型转换,代码更简洁
return Double.compare(o1.getRadius(), o2.getRadius());
}
}
import java.util.Comparator;
public class TestGeneric {
public static void main(String[] args) {
CircleComparator com = new CircleComparator();
System.out.println(com.compare(new Circle(1), new Circle(2)));
//System.out.println(com.compare("圆1", "圆2"));//编译错误,因为"圆1", "圆2"不是Circle类型,编译器提前报错,而不是冒着风险在运行时再报错
}
}
泛型类与泛型接口
声明
【修饰符】 class 类名<类型变量列表>{
//类型变量不能用于静态成员上
}
【修饰符】 interface 接口名<类型变量列表>{
}
使用
实际类型参数必须是引用数据类型,不能是基本数据类型
在创建类的对象时指定类型变量对应的实际类型参数
public class Student<T>{ private String name; private T score; public Student() { super(); } public Student(String name, T score) { super(); this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public T getScore() { return score; } public void setScore(T score) { this.score = score; } @Override public String toString() { return "姓名:" + name + ", 成绩:" + score; } }
public class TestGeneric{ public static void main(String[] args) { //语文老师使用时: Student<String> stu1 = new Student<String>("张三", "良好"); //数学老师使用时: //Student<double> stu2 = new Student<double>("张三", 90.5);//错误,必须是引用数据类型 Student<Double> stu2 = new Student<Double>("张三", 90.5); //英语老师使用时: Student<Character> stu3 = new Student<Character>("张三", 'C'); //错误的指定 //Student<Object> stu = new Student<String>();//错误的 } }
类型变量的上下限
语法格式
<类型变量 extends 上限>
<类型变量 extends 上限1 & 上限2>
<? extends 上限>
<? super 下限>
//如果没有指定上限,则默认时Object
泛型方法
语法格式
【修饰符】 <类型变量列表> 返回值类型 方法名(【形参列表】)【throws 异常列表】{
//...
}
类型通配符
声明一个方法时,不确定泛型的实际类型,则使用泛型通配符
class StudentService { public static void print(Student<?>[] arr) { for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }
public class TestGeneric { public static void main(String[] args) { // 语文老师使用时: Student<String> stu1 = new Student<String>("张三", "良好"); // 数学老师使用时: // Student<double> stu2 = new Student<double>("张三", 90.5);//错误,必须是引用数据类型 Student<Double> stu2 = new Student<Double>("张三", 90.5); // 英语老师使用时: Student<Character> stu3 = new Student<Character>("张三", 'C'); Student<?>[] arr = new Student[3]; arr[0] = stu1; arr[1] = stu2; arr[2] = stu3; StudentService.print(arr); } }