卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与面向对象

    • 面向对象三大特性
    • 面向对象和面向过程的区别是什么?
    • 抽象类和接口的区别?
    • 说说你对多态的理解?
    • Java中的方法重载和方法重写有什么区别?
    • Java中的final关键字可以修饰什么?被final修饰后有什么特点?
    • equals方法和==的区别
    • 堆和栈的区别?
    • 解释一下Java中的泛型及其作用?
      • 简要回答
      • 详细回答
      • 知识拓展
  • 集合

  • 异常

  • 字符串

  • JVM

  • 并发与多线程

  • JDK

  • Spring

  • 设计模式

# Java泛型

# 简要回答

  1. 泛型的概念:
    • 泛型(Generics)是 Java 的一种参数化类型机制,允许在定义类、接口或方法时声明类型参数,并在使用时指定具体类型,实现类型安全的代码复用。
  2. 泛型的作用:
    • 类型安全:泛型强制在编译时检查类型匹配,避免运行时出现 ClassCastException。
    • 消除强制转换:泛型自动处理类型转换,无需手动进行强制类型转换。
    • 代码复用:适用于编写通用算法和数据结构(如 List<T>、Map<K,V>)。
  3. 泛型的应用:
    • 自定义泛型类:泛型最后代表的数据类型是在创建对象时确定的。
    • 自定义泛型接口:泛型最终代表的数据类型是在继承该接口或者实现该接口时确定的。
    • 自定义泛型方法:泛型最终代表的数据类型是在调用方法时确定的,每次调用泛型方法,都可以指定不同的泛型类型。
    • 通过使用通配符(?)和边界(<? extends T>、<? super T>),可以实现灵活的类型匹配。

# 详细回答

  1. 泛型的概念:
    • 定义:
      泛型(Generics),又称参数化类型(Parameterized Types),是一种可以“表示其他数据类型”的数据类型。泛型是JDK5.0中出现的新特性,解决数据类型的安全性问题,在类声明或实例化时只要指定好具体的类型即可。
    • 语法:
      ① 在指定泛型时,必须要求 最终确定的数据类型为引用类型 ,而不可以是基本数据类型。
      ② 若在定义类时使用了泛型,实例化该类时却什么都没有传入,默认使用Object类型。
    • 特性:
      ① 类型参数化:在定义类、接口或方法时声明 类型参数,实际使用时再指定 具体类型。
      ② 类型擦除(Type Erasure):泛型仅在编译期存在,运行时 类型参数会被擦除。
      ③ 编译时类型检查:编译器会确保泛型代码的 类型一致性,防止非法赋值或操作。
  2. 泛型的作用:
    • 类型安全:
      泛型强制在编译时检查类型匹配,避免运行时出现 ClassCastException。
    • 消除强制转换:
      泛型自动处理类型转换,无需手动进行强制类型转换。
    • 代码复用: 通过泛型抽象化类型,可以实现 通用算法和数据结构。例如,Collections.sort() 可排序任何实现了 Comparable<T> 接口的类型。
  3. 泛型的应用:
    • 自定义泛型类:
      ① 泛型最后代表的数据类型是在创建对象时确定的;如果在创建泛型类对象时没有给出指定类型,默认会以Object替代。
      ② 自定义泛型类中,类的非静态成员可以使用泛型(属性,方法,构造器等);静态成员则不可以使用类的泛型。
      ③ 在自定义泛型类中,使用了泛型的数组只可以被定义,不可以被初始化。
    • 自定义泛型接口:
      ① 泛型最终代表的数据类型是在继承该接口或者实现该接口时确定的;若在使用时没有给出具体泛型,默认使用Object类型替代。
      ② 同自定义泛型类一样,自定义泛型接口的静态成员也不能使用泛型。
    • 自定义泛型方法:
      ① 泛型最终代表的数据类型是在调用方法时确定的,每次调用泛型方法,都可以指定不同的泛型类型。
      ② 自定义泛型方法,既可以定义在普通类中,也可以定义在泛型类中。
      ③ 注意区分自定义泛型方法 和 泛型在方法上的应用。,如下所示:
      //以下代码仅作为演示,无实际意义
      class<T, U> Watermelon {
      	public<K> void taste(T t, U u, K k) {
      		System.out.println(" T 和 U 代表泛型在方法上的应用;而 K 则是自定义泛型方法的使用。");
      	}
      }
      
      1
      2
      3
      4
      5
      6
    • 通配符与边界: Java 泛型默认是不变的(Invariant),即 List<String> 并不是 List<Object> 的子类型。为了增加泛型的灵活性和类型兼容性,引入了通配符和边界。
      ① 无界通配符 <?> :单独使用表示未知类型,支持任意泛型类型。例如 List<?>,它通常是可读不可写的(除了 null)。
      ② 上界通配符 <? extends T> :表示支持 T 类以及 T 类的子类,规定了泛型的上限。它实现了协变(Covariance),主要用于 生产者(Producer) 场景,即从集合中读取数据。
      ③ 下界通配符 <? super T> :表示支持 T 类以及 T 类的父类,规定了泛型的下限。它实现了逆变(Contravariance),主要用于 消费者(Consumer) 场景,即向集合中写入数据。

# 知识拓展

# 泛型的图解

  1. 引入泛型前 和 引入泛型后 的对比图 如下: image

# 类型擦除(Type Erasure)

  1. 类型擦除的本质:类型擦除的核心规则是:

    • 泛型类型参数在编译后会被擦除,替换为原始类型(Raw Type)或边界类型(Bound)。
    • 泛型仅在编译期存在,运行时无法获取类型参数的具体信息(如 List<String> 运行时仅为 List)。
  2. 擦除规则:

    • 无界类型参数(<T>):替换为 Object。

      // 编译前
      public class Box<T> { private T data; }
      // 编译后(字节码等效)
      public class Box { private Object data; }
      
      1
      2
      3
      4
    • 有界类型参数(<T extends Number>):替换为边界类型(如 Number)。

      // 编译前
      public class NumericBox<T extends Number> { private T data; }
      // 编译后
      public class NumericBox { private Number data; }
      
      1
      2
      3
      4
  3. 类型擦除的影响与限制:

    • 运行时类型信息丢失:

      List<String> strList = new ArrayList<>();
      List<Integer> intList = new ArrayList<>();
      // 以下结果为 true,因为两者运行时类型均为 ArrayList
      System.out.println(strList.getClass() == intList.getClass());
      
      1
      2
      3
      4
    • 无法实例化类型参数:

      public class Box<T> {
      	// 编译错误:Cannot instantiate the type T
      	private T instance = new T();
      }
      
      1
      2
      3
      4
    • 无法检查泛型类型:

      if (list instanceof List<String>) {} // 编译错误
      
      1
    • 重载冲突: 类型擦除后,以下方法会因签名相同导致编译错误:

      void print(List<String> list) {}
      void print(List<Integer> list) {} // 编译报错
      
      1
      2

Last Updated: 3/10/2026, 6:08:48 PM

← 堆和栈的区别? Java常见集合类有哪些? →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪