前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java之泛型:解读类型安全的利器

Java之泛型:解读类型安全的利器

原创
作者头像
喵手
发布2023-11-21 11:36:43
1640
发布2023-11-21 11:36:43
举报
文章被收录于专栏:Java进阶实战Java进阶实战

theme: healer-readable

highlight: a11y-dark


哈喽,各位小伙伴们,你们好呀,我是喵手。

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

在Java开发中,经常需要处理各种数据类型。但是,传统的Java使用Object类型作为通用数据类型会存在一些问题,如数据类型的转换等。Java泛型的出现就是为了解决这些问题。

摘要

本文将介绍Java泛型的基本概念、语法和应用场景。通过对源代码的分析和案例的讲解,掌握泛型的使用方法和操作技巧,同时分析泛型的优缺点,并介绍相应的应用实例。最后,通过测试用例对泛型的使用进行验证,总结泛型的特点和使用场景。

泛型

简介

Java泛型是Java 5的新特性,是一种将数据类型参数化的机制。它可以使编译器在编译时强制进行类型检查,从而提高代码的可读性和安全性。

泛型可以在类、接口、方法中定义类型参数,使得它们可以使用不同类型的对象而不需要进行数据类型转换。泛型的出现使得程序员可以编写更加通用、类型安全、可重用和简洁的代码。

源代码解析

Java泛型的关键就在于定义类型参数。Java泛型的定义采用尖括号“<>”将类型参数括在一起,如下所示:

代码语言:java
复制
class ClassName<T> {  
    // ...
}

其中,T为类型参数,可以是任意非关键字的标识符。通过使用T来代表类型参数,可以在类或方法内部使用该类型。通过在实例化类或调用方法时指定具体类型,可以在编译时进行类型检查。

这是一个泛型类定义,其中 T 是泛型类型参数。它表示该类可以接受任意类型的参数。在类的定义中,可以使用 T 作为类型参数定义类中的各种成员变量、方法或构造函数等。在实例化该泛型类时,会指定实际的类型参数来替换 T。例如:

代码语言:txt
复制
ClassName<String> instance = new ClassName<>();

这里实例化了一个 ClassName 类,其中 T 被替换为 String 类型。这意味着在该实例中,可以使用 String 类型的成员变量、方法或构造函数等。

除了类型参数,还有通配符类型参数?,可以用来表示不确定的类型。例如:

代码语言:java
复制
public void printList(List<?> list) {
  // ...
}

该方法接受一个List类型的参数,该List中的元素类型可以是任意类型,但是不确定具体是什么类型。

应用场景案例

集合类中使用泛型

在Java集合类中,最常见的使用泛型的地方是在List、Set和Map等容器类中。例如:

代码语言:java
复制
List<String> list = new ArrayList<String>();
Set<Integer> set = new HashSet<Integer>();
Map<String, Integer> map = new HashMap<String, Integer>();

这里定义了一个List类型的集合,其中只能添加String类型的元素;定义了一个Set类型的集合,其中只能添加Integer类型的元素;定义了一个Map类型的集合,其中Key的类型是String,Value的类型是Integer。

自定义泛型类和泛型方法

我们也可以自定义泛型类和泛型方法。例如,我们定义一个泛型类来表示一对数据:

代码语言:java
复制
class Pair<T, V> {
  private T first;
  private V second;
  public Pair(T first, V second) {
    this.first = first;
    this.second = second;
  }
  // 省略其他代码
}

这里定义了一个类Pair,它包含两个类型参数TV,分别表示第一个数据和第二个数据的类型。我们还可以定义泛型方法来操作泛型类型:

代码语言:java
复制
public static <T> T getMax(T[] array) {
  T max = array[0];
  for (int i = 1; i < array.length; i++) {
    if (array[i].compareTo(max) > 0) {
      max = array[i];
    }
  }
  return max;
}

该方法接收一个泛型数组,返回其中最大的元素。这里使用了类型参数T表示数组中元素的类型。通过compareTo方法比较数组中元素的大小,返回最大元素。

优缺点分析

优点

  1. 提高代码的可读性和安全性;
  2. 实现了代码的类型安全检查,减少了运行时的错误;
  3. 可以在编译时检查代码的类型安全,避免了数据类型转换的问题;
  4. 实现了代码的重用性和通用性。

缺点

  1. 在某些情况下,使用泛型会导致代码的可读性降低;
  2. 泛型的类型参数不能是基本数据类型,只能使用其对应的包装类;
  3. 不能使用泛型数组,只能使用泛型容器。

类代码方法介绍

泛型类

在Java中,泛型类用<T>来替代具体的数据类型。

代码语言:java
复制
package com.example.javase.se.classes.generic;

import java.util.List;

/**
 * @Author ms
 * @Date 2023-11-05 19:10
 */
class Pair<T extends Comparable<T>, V> {

    private T first;
    private V second;

    public Pair(T first, V second) {
        this.first = first;
        this.second = second;
    }

    public Pair() {
    }


    public static Integer getMax(List<Pair<String, Integer>> array) {
        Integer max = array.get(0).second;
        for (int i = 1; i < array.size(); i++) {
            if (array.get(i).second > max) {
                max = array.get(i).second;
            }
        }
        return max;
    }

    @Override
    public String toString() {
        return "Pair{" +
                "first=" + first +
                ", second=" + second +
                '}';
    }
}

这里定义了一个泛型类Pair,包含两个类型参数TV,分别表示第一个数据和第二个数据的类型。通过<T, V>声明类型参数。

该代码定义了一个泛型类Pair,其中含有两个成员变量firstsecond,分别表示泛型类型TV的第一个和第二个值。类中包含了一个有限制的泛型方法getMax,用于返回一个列表中第二个值最大的整数。该方法使用了通配符? extends Comparable<?>来限制泛型类型T必须实现Comparable接口,以便能够进行比较操作。在实例化该类时,可以指定TV的具体类型,也可以不指定,使用默认值。类中还包含了一个重写的toString方法,用于将实例对象转化为字符串。

泛型方法

在Java中,泛型方法需要在方法名前面添加类型参数列表,用<T>来替代具体的数据类型。

代码语言:java
复制
    public static Integer getMax(List<Pair<String, Integer>> array) {
        Integer max = array.get(0).second;
        for (int i = 1; i < array.size(); i++) {
            if (array.get(i).second > max) {
                max = array.get(i).second;
            }
        }
        return max;
    }

这里定义了一个泛型方法getMax,它接收一个泛型数组,并返回其中最大的元素。通过<T>声明类型参数。

通配符

通配符可以用来表示不确定的类型,写法为<?>。例如:

代码语言:java
复制
public void printList(List<?> list) {
  // ...
}

这里定义了一个方法printList,它接收一个List类型的参数,该List中的元素类型可以是任何类型。

测试用例

代码语言:java
复制
package com.example.javase.se.classes.generic;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author ms
 * @Date 2023-11-05 19:10
 */
public class Test {
    public static void main(String[] args) {
        Pair<String, Integer> p1 = new Pair<>("Java", 5);
        Pair<String, Integer> p2 = new Pair<>("Python", 7);
        Pair<String, Integer> p3 = new Pair<>("C++", 3);

        List<Pair<String, Integer>> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);

        Integer maxPair = Pair.getMax(list);
        System.out.println("Max Pair: " + maxPair);
    }
}

该测试用例测试了Pair类和Pair类的泛型方法getMax。首先创建了三个Pair对象,并将它们添加到一个List中。然后调用getMax方法,返回其中最大的元素。

测试结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述
在这里插入图片描述

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。

这段代码演示了如何使用泛型类Pair及其静态方法getMax来实现获取列表中最大值的功能。

首先,我们定义了三个Pair对象p1、p2、p3,这些对象分别包含了一个String类型的值和一个Integer类型的值。

接着,我们创建了一个List对象list,并向其添加了p1、p2、p3三个对象。

最后,我们调用Pair类的静态方法getMax来获取list列表中所有Pair对象中的最大值,并将结果保存在一个Integer类型的变量maxPair中。最终,我们将maxPair打印输出。

值得注意的是,因为Pair类中定义了泛型类型\<T extends Comparable<T>>,所以我们才可以使用Pair类提供的getMax方法来获取最大值。此外,我们定义的列表list中的元素类型也必须与Pair对象的类型一致,即都是Pair\<String, Integer>类型。

小结

本文介绍了Java泛型的基本概念、语法和应用场景。通过对源代码的分析和案例的讲解,掌握了泛型的使用方法和操作技巧,同时分析了泛型的优缺点,并介绍了相应的应用实例。最后,通过测试用例对泛型的使用进行了验证,总结了泛型的特点和使用场景。

总结

Java泛型是Java 5的新特性,是一种将数据类型参数化的机制。它可以使编译器在编译时强制进行类型检查,从而提高代码的可读性和安全性。泛型可以在类、接口、方法中定义类型参数,使得它们可以使用不同类型的对象而不需要进行数据类型转换。泛型的出现使得程序员可以编写更加通用、类型安全、可重用和简洁的代码。

... ...

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

... ...

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 摘要
  • 泛型
    • 简介
      • 源代码解析
        • 应用场景案例
          • 集合类中使用泛型
          • 自定义泛型类和泛型方法
        • 优缺点分析
          • 优点
          • 缺点
        • 类代码方法介绍
          • 泛型类
          • 泛型方法
          • 通配符
        • 测试用例
          • 测试结果
          • 测试代码分析
        • 小结
        • 总结
        • 文末
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档