Java 泛型

本文详细介绍了Java中的泛型,包括泛型的基本概念、泛型方法的使用、泛型接口的实现以及泛型类的实例。通过示例代码展示了泛型在不同场景下的应用,如类型安全、类型推断等,并讨论了Java泛型的伪泛型特性和泛型通配符的使用,包括上界和下界通配符。此外,还提及了有约束的泛型及其在实际编程中的作用。

泛型

  • 泛型,即“参数化类型”,将数据类型作为一种可以传参的变量
  • 泛型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

泛型方法

public class Test {  
    public static void main(String[] args) {  
 
        /**不指定泛型的时候*/  
        int i = Test.add(1, 2); //这两个参数都是Integer,所以T为Integer类型  
        Number f = Test.add(1, 1.2); //这两个参数一个是Integer,一个是Float,所以取同一父类的最小级,为Number  
        Object o = Test.add(1, "asd"); //这两个参数一个是Integer,一个是String,所以取同一父类的最小级,为Object
 
        /**指定泛型的时候*/  
        int a = Test.<Integer>add(1, 2); //指定了Integer,所以只能为Integer类型或者其子类  
        int b = Test.<Integer>add(1, 2.2); //编译错误,指定了Integer,不能为Float  
        Number c = Test.<Number>add(1, 2.2); //指定为Number,所以可以为Integer和Float  
    }  
 
    //这是一个简单的泛型方法  
    public static <T> T add(T x,T y){  
        return y;  
    }  
}
  • 即对于方法的形参类型、返回值类型等也作为一种需要传递具体参数值的变量,只有在调用该方法时传入了固定类型的参数后这个方法的入参和返回值类型才算确定
  • 不能声明泛型的静态方法,在泛型类中,静态方法的返回值可以是泛型

泛型接口

public interface Generator<T> {
    public T method();
}
  • 有两种实现方式
    1.实现的时候指定具体的类型
    2.实现的时候依然是泛型,泛型实现类实例化的时候,再指定具体的类型
class GeneratorImpl<T> implements Generator<String>{
    @Override
    public String method() {
        return "hello";
    }
}
class GeneratorImpl<T> implements Generator<T>{
    @Override
    public T method() {
        return null;
    }
}

泛型类

/**
 * Java泛型
 */
public class Demo {
    public static void main(String[] args) {
        // 定义泛型类 Test 的一个Integer版本
        Test<Integer> intOb = new Test<Integer>(88);
        intOb.showType();
        int i = intOb.getOb();
        System.out.println("value= " + i);
        System.out.println("----------------------------------");
        // 定义泛型类Test的一个String版本
        Test<String> strOb = new Test<String>("Hello Gen!");
        strOb.showType();
        String s = strOb.getOb();
        System.out.println("value= " + s);
    }
}
/*
使用T代表类型,无论何时都没有比这更具体的类型来区分它。如果有多个类型参数,我们可能使用字母表中T的临近的字母,比如S。
注意:父类定义的类型参数不能被子类继承
*/
class Test<T> {
    /*
    定义泛型成员变量
    */
     private T ob;
 
    //构造函数
    public Test(T ob) {
        this.ob = ob;
    }
 
    //getter 方法
    public T getOb() {
        return ob;
    }
 
 
    //setter 方法
    public void setOb(T ob) {
        this.ob = ob;
    }
 
    public void showType() {
        System.out.println("T的实际类型是: " + ob.getClass().getName());
    }
}
 
/* output
    T的实际类型是: java.lang.Integer
    value= 88
    ----------------------------------
    T的实际类型是: java.lang.String
    value= Hello Gen!
*/

伪泛型

  • Java中的泛型是伪泛型,用的是擦除法,在代码编译为class文件时,会把泛型换成对应的数据类型的数据处理,在处理前还会加上类型intance of 判断。如果编译为class文件依然没有指定某一数据类型,则擦除法会直接将泛型替换为Object
  • 对于真泛型的语言,泛型本身是一种真实存在的数据类型,比如List<Person>的子类可以是List<Student>List<Teacher>等(Student、Teacher均为Person的子类),而Java明显不满足

泛型通配符

  • 泛型就是将数据类型也作为一种可以传参的变量,泛型通配符即为变量名,就像其他变量的变量名,理论上可以使任意的字符表示,但是依然有一套约定俗成的命名
  • 约定的泛型通配符
    ? 表示不确定的 java 类型
    T (type) 表示具体的一个java类型
    K V (key value) 分别代表java键值中的Key Value
    E (element) 代表Element

有约束的泛型

  • 上界通配符 < ? extends E>:用 extends 关键字声明,表示参数化的类型可能是所指定的类型E,或者是此类型的子类
  • 下界通配符 < ? super E>:用 super 进行声明,表示参数化的类型可能是所指定的类型E,或者是此类型的父类型,直至 Object
  • 其他泛型: <T extends A&B&C…> 多个继承条件的泛型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值