码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • JDK1.5后增加了泛型,那么为什么要有泛型呢?我们该如何自定义泛型结构呢?


    本篇主要讲解java泛型的理解、集合中简单使用泛型、自定义泛型结构(包括类、接口、方法)。


    一、什么是泛型?

    通俗来讲,可以把泛型理解为带有标签的罐子,罐子贴着红糖的标签,就只能放红糖;罐子贴着白糖的标签,就只能放白糖,不可以乱放。用集合来解释,可以理解为:

    list贴上了String的泛型标签,就只能添加String类型的数据;list1贴上了Integer的泛型标签,就只能添加Integer类型的数据;否则就会报错。


    二、泛型的概念

    • 所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类 型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如, 继承或实现这个接口,用这个类型声明变量、创建对象)确定(即传入实 际的类型参数,也称为类型实参)。
    • 从JDK1.5以后,Java引入了“参数化类型(Parameterized type)”的概念,允许我们在创建集合时再指定集合元素的类型,比如:List,这表明该List只能保存字符串类型的对象。
    • JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持, 从而可以在声明集合变量、创建集合对象时传入类型实参。
    • 简单的看一下List接口中的泛型
    1. public interface List<E> extends Collection<E> {
    2. Iterator iterator();
    3. T[] toArray(T[] a);
    4. boolean add(E e);

    三、为什么要设计泛型?

    所以为什么要有泛型呢?直接用Object类型存储数据不香吗?

    以集合为例,当我们不使用泛型时:

    1. public void test1() {
    2. List list = new ArrayList<>();
    3. list.add(123);
    4. list.add(456);
    5. list.add("789");
    6. for (Object o : list) {
    7. Integer item = (Integer) o;
    8. System.out.println(item);
    9. }
    10. }
    11. 运行结果:

      当我们使用泛型时:

      1. public void test2() {
      2. List list = new ArrayList<>();
      3. list.add(123);
      4. list.add(456);
      5. // list.add("789");添加失败
      6. for (Integer integer : list) {
      7. System.out.println(integer);
      8. }
      9. }

      我们可以发现,使用泛型后,当添加的数据类型不满足条件时,编译就会报错;在遍历集合时,还可以避免强制类型转换。


      四、自定义泛型结构

      1、自定义泛型类

      1. public class Order<T> {
      2. String orderName;
      3. int orderId;
      4. //类的内部结构就可以使用类的泛型
      5. T orderT;
      6. //构造器
      7. public Order(){
      8. //泛型数组
      9. T[] arr = (T[]) new Object[8];
      10. }
      11. public Order(String orderName,int orderId,T orderT){
      12. this.orderName = orderName;
      13. this.orderId = orderId;
      14. this.orderT = orderT;
      15. }
      16. //注意,下面的三个方法都不是泛型方法
      17. public T getOrderT(){
      18. return orderT;
      19. }
      20. public void setOrderT(T orderT){
      21. this.orderT = orderT;
      22. }
      23. @Override
      24. public String toString() {
      25. return "Order{" +
      26. "orderName='" + orderName + '\'' +
      27. ", orderId=" + orderId +
      28. ", orderT=" + orderT +
      29. '}';
      30. }
      31. }

      需要注意的是:

      • 异常类不能声明为泛型:

      • 编译不通过:

      • 静态方法中不能使用泛型:因为是静态方法,即可以使用类来调用;当使用类来调用方法时,并不知道参数T指的是什么,所以不行。当使用对象调用方法时,通过构造器创建对象时,就已经指明了T是什么类型。


      2、自定义泛型接口

      由于类和接口没有很大的区别,所以为了文章的完整性,就继续以类来讲解泛型相关的知识:

      1. class Father, T2> {
      2. }
      3. // 子类不保留父类的泛型
      4. // 1)没有类型 擦除
      5. class Son1 extends Father {// 等价于class Son extends Father{
      6. }
      7. // 2)具体类型
      8. class Son2 extends Father, String> {
      9. }
      10. // 子类保留父类的泛型
      11. // 1)全部保留
      12. class Son3, T2> extends Father, T2> {
      13. }
      14. // 2)部分保留
      15. class Son4 extends Father, T2> {
      16. }
      1. class Father, T2> {
      2. }
      3. // 子类不保留父类的泛型
      4. // 1)没有类型 擦除
      5. class Son, B> extends Father{//等价于class Son extends Father{
      6. }
      7. // 2)具体类型
      8. class Son2, B> extends Father, String> {
      9. }
      10. // 子类保留父类的泛型
      11. // 1)全部保留
      12. class Son3, T2, A, B> extends Father, T2> {
      13. }
      14. // 2)部分保留
      15. class Son4, A, B> extends Father, T2> {
      16. }

      总结:

      • 泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价 于Object。经验:泛型要使用一路都用。要不用,一路都不要用。
      • 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
      • 泛型的指定中不能使用基本数据类型,可以使用包装类替换。

      3、自定义泛型方法

      • 方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。
      • 泛型方法的格式:[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
      1. //这些都是泛型方法:
      2. public void say(List list) { }
      3. public static List copyFromArrayToList(E[] arr) {
      4. ArrayList list = new ArrayList<>();
      5. for (E e : arr)
      6. list.add(e);
      7. return list;
      8. }
    12. 相关阅读:
      https 原理与实践
      智能时代的智能工具(gpt)国产化助手
      红队打靶:Misdirection打靶思路详解(vulnhub)
      初学者对html的认知
      【基本算法题-2022.7.27】5. 递归实现指数型枚举
      python使用字符串的格式化方法来设置字符串的固定长度
      文件操作(详解!)
      集团资金管理BI分析的三个关键节点
      Qt槽函数的几种写法
      13薪|18k-30k -JAVA开发工程师[北京市 - 海淀区]
    13. 原文地址:https://blog.csdn.net/LBWNB_Java/article/details/126297749
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | Kerberos协议及其部分攻击手法
        0day的产生 | 不懂代码的"代码审计"
        安装scrcpy-client模块av模块异常,环境问题解决方案
        leetcode hot100【LeetCode 279. 完全平方数】java实现
        OpenWrt下安装Mosquitto
        AnatoMask论文汇总
        【AI日记】24.11.01 LangChain、openai api和github copilot
      • 热门文章
      • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
        奉劝各位学弟学妹们,该打造你的技术影响力了!
        五年了,我在 CSDN 的两个一百万。
        Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
        面试官都震惊,你这网络基础可以啊!
        你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
        心情不好的时候,用 Python 画棵樱花树送给自己吧
        通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
        13 万字 C 语言从入门到精通保姆级教程2021 年版
        10行代码集2000张美女图,Python爬虫120例,再上征途
      Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
      正则表达式工具 cron表达式工具 密码生成工具

      京公网安备 11010502049817号