Java 泛型的学习

18 篇文章 0 订阅
18 篇文章 0 订阅

虽然写了一段时间的 Java 代码,但是一直以来只要看到泛型,还是会摸不着头脑选择性放弃。但是今天在看公司大佬的代码发现很多地方会用到泛型,所以今天就整理一下我理解的泛型。

什么是泛型

泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。 泛型的定义主要有以下两种: 1⃣️ 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。 2⃣️ 在程序编码中一些包含参数的类。其参数可以代表类或对象等等。

👆上面的解释来自百度百科,简单的说 泛型是一种代码范式。

Java 泛型

Java 泛型的参数只可以代表类,不能代表个别对象。由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型,而且无法直接使用基本值类型作为泛型类型参数。

Java 泛型设计原则:

把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型。只要在编译时期没有出现警告,那么运行时期就不会出现 ClassCastException 异常。

下面是简单的泛型的例子:

public class Generic {

    public static void main(String[] args) {
        // C 可以接受 String
        C<String> stringC = new C<>("Hello world");
        System.out.println(stringC);
        
        // C 可以接受 Integer
        C<Integer> integerC = new C<>(100);
        System.out.println(integerC);

    }
}

// C 可以接受任意类型数据的初始化
class C<T> {
    private T item;

    public C(T t){
        item = t;
    }

    @Override
    public String toString() {
        return  item + "";
    }
}
复制代码

T、E、K、V

T、E、K、V 本质上都是通配符。编码有时候讲究约定俗成。比如我们可以用 A-Z 之间的任何一个字母都可以表示通配符,并不会影响程序的正常运行。通常情况下 T、E、K、V 是这样约定的:

  • 表示不确定的 Java 类型
  • T ( type ) 表示具体的一个 Java 类型
  • K V ( key value ) 分别代表 Java 键值中的 Key Value
  • E ( element ) 代表 Element

通配符

  • 上界通配符 ? extends T

    例如 List< ? extends Number>目的是为了接受List<Integer> or List<Long>的数据类型。

  • 下界通配符 ? super T

    例如 List<? super Number> 目的是为了弥补只能存放一种特定类型数据的不足。

public class Generic {

    public static void main(String[] args) {
        // 可以
        List<? super Number> list = new ArrayList<>();
        list.add(10);
        list.add(20L);
        list.add(20.2);

        System.out.println(list);

        List<Integer> list1 = new ArrayList<>();
        List<Long> list2 = new ArrayList<>();

        list1.add(10);
        list1.add(20);

        list2.add(10L);
        list2.add(20L);

        read(list1);
        read(list2);
    }

    private static void read(List< ? extends Number> list) {
        Number first = list.get(0);
        Number last = list.get(list.size() - 1);
        System.out.println("first = " + first.toString() + " last = " + last.toString());
    }
    
}
复制代码

最后看一下 PECS(Producer Extends Consumer Super)原则:

  • 频繁往外读取内容的,适合用上界 Extends
  • 经常往里插入的,适合用下界 Super

泛型案例

// 多参数泛型 
class Person<N, A, S> {

    private N name;
    private A age;
    private S sex;

    Person(N name, A age, S sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public N getName() {
        return name;
    }
    public void setName(N name) {
        this.name = name;
    }
    public A getAge() {
        return age;
    }
    public void setAge(A age) {
        this.age = age;
    }
    public S getSex() {
        return sex;
    }
    public void setSex(S sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "姓名:" + name + ",年龄:" + age + ",性别:" + sex;
    }
}

// 使用
public class Generic {

    public static void main(String[] args) {

        Person<String, Integer, Character> person = new Person<String, Integer, Character>("蛋炒饭", 28, '男');
        printPerson(person);
        // 姓名:蛋炒饭,年龄:28,性别:男
    }
    
    // 泛型方法
    private static <T> void printPerson(T person){
        if ( person != null) {
            System.out.println(person);
        }
    }
}
复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值