18 泛型
lix_uan 612 1

泛型的概念

  • 在声明方法时,有未知参数参与,这些数据的类型需要在方法调用时才能确定

  • 所以JDK1.5引入了泛型的概念,用来代表未知的通用的类型 18 泛型

示例

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);
        }
    }
评论区

索引目录