所谓泛型类就是把当我们在声明类时,类中的有些成员的类型并不是确定,然后我们可以把泛型定义在类上,当使用该类的时候,再把不确定成员的类型明确下来。
语法格式
【修饰符】 class 类名<类型变量列表>{
//类体
}
注: <类型变量列表>:可以是一个或多个类型变量,一般都是使用单个的大写字母表示。例如:、<K,V>等。
<类型变量列表>中的类型变量不能用于静态成员上。
泛型类的使用
使用这种类似于参数化类型的类时,在创建类的对象时候,我们需要注意:
-
指定类型变量对应的实际类型参数
-
实际类型参数必须是引用数据类型,不能是基本数据类型
注:指定泛型实参时,必须左右两边一致,不存在多态现象(右边的可以省略不写)
代码示例
/*
泛型类的声明与使用
*/
public class Demo1 {
public static void main(String[] args) {
//泛型类的使用(里面只能是引用类型)
Student student1 = new Student<>(“学生1”,99.5);
Student student2 = new Student<>(“学生2”,“优秀”);
Student student3 = new Student<>(“学生3”,‘A’);
//输出结果
System.out.println(student1);
System.out.println(student2);
System.out.println(student3);
}
}
//泛型类的声明
class Student { //这个就是泛型类的类型参数
private String name;
private T score; //使用泛型,定义分数(分数可能有double类型(99.5)、字符串类型(优秀)、字符类型(‘A’)等)
//构造方法
public Student() {
}
public Student(String name, T score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return “Student{” +
“name='” + name + ‘’’ +
“, score=” + score +
‘}’;
}
}
泛型接口和泛型类关系,就像接口和类的关系一样。 这里不多说。
语法格式
【修饰符】 interface 接口名<类型变量列表>{
}
注: <类型变量列表>:可以是一个或多个类型变量,一般都是使用单个的大写字母表示。例如:、<K,V>等。
<类型变量列表>中的类型变量不能用于静态成员上。
泛型接口的使用
使用这种类似于参数化类型的接口时,我们需要注意:
-
指定类型变量对应的实际类型参数
-
实际类型参数必须是引用数据类型,不能是基本数据类型
代码示例
/*
泛型接口的声明与使用
*/
public class Demo1 {
public static void main(String[] args) {
//泛型类的使用(里面只能是引用类型)
Student student1 = new Student<>(“学生1”,99.5);
//使用泛型接口
student1.print(“学生1”,99.5);
}
}
//泛型类的声明
class Student implements Print<String,T>{ //这个就是泛型类的,后面<String,T>是接口,多个类型变量
private String name;
private T score; //使用泛型
//构造方法
public Student() {
}
public Student(String name, T score) {
this.name = name;
this.score = score;
}
//重写接口的方法
@Override
public void print(String s, T t) {
System.out.println(“学生姓名:”+ this.name);
System.out.println(“学生成绩:”+ this.score);
}
}
//泛型接口的声明
interface Print <T,V>{
//定义一个打印函数,可以打印学生姓名和成绩
public void print(T t, V v);
}
前面说到,我们可以使用泛型类型参数,这样等我们进行实际使用的时候,我们可以任意使用类型,但如果想只使用某一系列的类型,泛型也是可以实现的。这就是我们说的类型变量的上限和类型变量的下限。下面进行分别介绍。
类型变量的上限
如果泛型类定义了类型变量的上限,那么该泛型类实际的类型只能是该上限类型或者其子类类型。
语法格式
泛型类和泛型方法的用法是一样的,后面都不再做区分。
<类型变量 extends 上限1 & 上限2> //上限可以有多个
注:如果多个上限中有类有接口,那么只能有一个类,而且必须写在最左边。接口的话,可以多个。
如果在声明<类型变量>时没有指定上限,默认上限是java.lang.Object。
代码示例
/*
类型变量的上限
*/
public class Demo2 {
public static void main(String[] args) {
Test test1 = new Test<>(77.5); //double类
// Test test2 = new Test(); 不是数字类的子类
Test test3 = new Test<>(18);
test1.print(77.5);
test3.print(18);
}
}
class Test{ //数字类上限,只能使用数字类及其子类
private T num;
public Test() {
}
public Test(T num) {
this.num = num;
}
public void print(T num){ //测试方法
System.out.println(num);
}
}
类型变量的下限
如果泛型类定义了类型变量的下限,那么该泛型类实际的类型只能是该下限类型或者其父类类型。