news 2026/4/19 1:27:58

java : 泛型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java : 泛型

1.泛型类的定义

泛型类是Java中一种可以参数化的类,它允许在定义类时不指定具体的类型,而是在实例化时再确定具体的类型参数。这种机制提高了代码的复用性和类型安全性。

1.1基本语法

  • 泛型类的定义语法
  • class 类名称 <泛型标识、泛型标识,...> { private 泛型标识 变量名; ...... }
  • 常用的泛型标识T、E、K、V

其中:

  • <T>表示类型参数声明
  • T是类型参数名(可以是任何有效的标识符,但通常使用单个大写字母)
  • 可以在类定义中使用T作为实际的类型

1.2 示例代码

​ /** * 泛型类的定义 * @param <T> 泛型标识-----类型形参 * T 创建对象的时候里面具体制定的数据类型 */ public class Generic<T> { // T 是由外部使用类的时候来指定的。 private T key; public Generic(T key) { this.key = key; } public T getKey() { return key; } public void setKey(T key) { this.key = key; } @Override public String toString() { return "Generic{" + "key=" + key + '}'; } } ​

1.3 使用场景

  1. 容器类:如集合框架中的ArrayList、HashMap等
  2. 工具类:如比较器Comparator
  3. 数据包装类:如Optional
  4. 自定义数据结构:如树、图等通用数据结构

1.4 多类型参数

泛型类可以定义多个类型参数:

public class Pair<K, V> { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } // getter和setter方法 }

1.5 类型参数约束

可以使用extends关键字对类型参数进行约束:

public class NumberBox<T extends Number> { private T number; public double getDoubleValue() { return number.doubleValue(); } }

1.6 注意事项

  1. 泛型类不能是基本数据类型(如int、char等)
  2. 类型擦除:Java泛型是通过类型擦除实现的,运行时类型信息会被擦除
  3. 静态成员不能使用类型参数
  4. 不能实例化类型参数(如new T()是不允许的)

2. 泛型类的使用语法

泛型类是Java中实现参数化类型的重要机制,它允许在定义类时指定类型参数,在使用时再确定具体类型。以下是泛型类的详细使用说明:

2.1. 泛型类的定义

  • 使用语法
类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();
  • java 1.7以后,后边的<>中具体的数据类型可以省略不写
类名<具体的数据类型> 对象名 = new 类名<>();

2.2 案例:

public static void main(String[] args) { // 泛型类在创建对象的时候来指定操作的具体数据类型 Generic<String> stringGeneric = new Generic<>("a"); String key = stringGeneric.getKey(); System.out.println("key:" + key); System.out.println("------------------------"); Generic<Integer> integerGeneric = new Generic<>(100); Integer key1 = integerGeneric.getKey(); System.out.println("key1:"+key1); // 总结:泛型的本质是参数化类型,也就是所操作的数据类型被指定为一个参数。 System.out.println("----------注意点1:--------------"); // 泛型类在创建对象的时候,没有指定泛型类,将按照Object类型来操作 Generic generic = new Generic("ABC"); Object key3 = generic.getKey(); System.out.println("key3:"+key3); System.out.println("----------注意点2:--------------"); // 泛型类不支持基本数据类型,原因就是我们在编译期间会将这个 T 编译成 Object // 基本数据类型无法转化为 object类型 // Generic<int> intGeneric = new Generic<>(100); System.out.println("----------注意点3:--------------"); // 同一泛型类,根据不同的数据类型创建的对象,本质上是同一类型 System.out.println(integerGeneric.getClass() == stringGeneric.getClass()); }

总结:泛型类使用要点

  1. 未指定具体数据类型时,操作类型默认为Object
  2. 类型参数仅支持类类型,不支持基本数据类型
  3. 逻辑上可视为不同类型,但实际运行时属于同一类型

年终抽奖器(可能会是奖金,也可能是奖品)

/** * 抽奖器 * @param <T> */ public class ProductGetter<T> { //奖金或者奖品 private T product; // 定义奖品、奖金池 ArrayList<T> arrayList = new ArrayList<>(); // 添加奖品到奖品池 public void addProduct(T t){ arrayList.add(t); } // 定义一个随机数,用来抽选奖品 Random random = new Random(); //抽奖 public T getProduct(){ product = arrayList.get(random.nextInt(arrayList.size())); return product; } }
public static void main(String[] args) { ProductGetter<String> stringProductGetter = new ProductGetter<>(); String[] strPro = {"苹果手机","华为手机","扫地机器人","咖啡机"}; //将奖品放入奖金池 for (int i = 0;i< strPro.length;i++){ stringProductGetter.addProduct(strPro[i]); } String product = stringProductGetter.getProduct(); System.out.println("恭喜您抽中了:"+product); System.out.println("******************************"); ProductGetter<Integer> IntegerProductGetter = new ProductGetter<>(); Integer[] intPro = {100,1000,10000,20000}; //将奖品放入奖金池 for (int i = 0;i< intPro.length;i++){ IntegerProductGetter.addProduct(intPro[i]); } Integer product1 = IntegerProductGetter.getProduct(); System.out.println("恭喜您,获的了:"+product1+"元"); }

3. 从泛型类派生子类(2种情况)

  • 子类也是泛型类,子类和父类的泛型类型要保持一致
class ChildGeneric<T> extends Generic<T>
  • 子类不是泛型类,父类要明确泛型类的数据类型
class ChildGeneric extends Generic<String>

第一种情况:子类和父类的泛型类型要保持一致

定义父类

public class Parent<E> { private E value; public E getValue() { return value; } public void setValue(E value) { this.value = value; } }

定义子类

/** * 泛型类派生子类,如果子类也是泛型类,子类的泛型标识要和父类一致。 * @param <T> */ public class ChildFirst<T> extends Parent<T> { @Override public T getValue() { return super.getValue(); } }

测试类

public static void main(String[] args) { ChildFirst<String> childFirst = new ChildFirst<>(); childFirst.setValue("123"); String value = childFirst.getValue(); System.out.println(value); }

第二种情况:子类没有使用 泛型

总结:子类不是泛型类,父类要明确泛型类的数据类型

4. 泛型接口

4.1 泛型接口的语法定义

interface 接口名称 <泛型标识,泛型标识,...>{ 泛型标识 方法名(); ...... }

4.2 泛型接口的使用(2种情况)

情况1:实现类不是泛型类,接口要明确数据类型

当实现类不是泛型类时,需要在实现接口时明确指定具体的数据类型。这种情况下,接口的泛型参数会被具体化为特定的类型。

示例:

// 泛型接口定义 interface DataContainer<T> { void add(T item); T get(int index); } // 非泛型实现类 class StringContainer implements DataContainer<String> { private List<String> items = new ArrayList<>(); @Override public void add(String item) { items.add(item); } @Override public String get(int index) { return items.get(index); } }

应用场景:

  • 当实现类只需要处理特定类型数据时
  • 例如专门处理字符串、整数等具体类型的容器类
  • 可以避免在实现类中使用泛型带来的复杂性

情况2:实现类也是泛型类,实现类和接口的泛型类型要一致

当实现类也是泛型类时,实现类的泛型参数必须与接口的泛型参数保持一致,这样才能确保类型安全。

示例:

// 泛型接口定义 interface DataContainer<T> { void add(T item); T get(int index); } // 泛型实现类 class GenericContainer<T> implements DataContainer<T> { private List<T> items = new ArrayList<>(); @Override public void add(T item) { items.add(item); } @Override public T get(int index) { return items.get(index); } }

应用场景:

  • 当需要创建通用的、可重用的组件时
  • 例如集合框架中的ArrayList、LinkedList等
  • 可以保持代码的灵活性和可扩展性

注意事项:

  1. 实现类的泛型参数名可以与接口不同,但类型参数数量必须一致
  2. 可以在实现类中添加额外的泛型参数
  3. 类型擦除后,编译器会确保类型安全
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 22:18:07

语音合成新突破:GPT-SoVITS实现跨语言TTS只需1分钟音频

语音合成新突破&#xff1a;GPT-SoVITS实现跨语言TTS只需1分钟音频 在内容创作日益个性化的今天&#xff0c;越来越多的自媒体人、教育工作者甚至普通用户开始思考一个问题&#xff1a;能不能让AI用我的声音说话&#xff1f; 过去&#xff0c;这听起来像是科幻电影的情节。传统…

作者头像 李华
网站建设 2026/4/18 4:46:06

Java矩阵乘法

任务描述 本关任务&#xff1a;编写一个程序&#xff0c;输入两个矩阵输出矩阵乘的结果。矩阵乘法 矩阵相乘最重要的方法是一般矩阵乘积。它只有在第一个矩阵的列数&#xff08; column &#xff09;和第二个矩阵的行数&#xff08; row &#xff09;相同时才有意义。 矩阵乘法…

作者头像 李华
网站建设 2026/4/18 7:36:42

提高领导能力必看的三本书

很多人一提到“领导力”&#xff0c;就会想到鼓舞人心的演讲、果断的决策、带领团队逆转困境的传奇故事。但现实中&#xff0c;大多数管理者面临的领导挑战&#xff0c;远比这些更细微也更真实——如何让团队信任你、如何在压力下保持判断、如何在复杂环境中做出平衡的选择。领…

作者头像 李华
网站建设 2026/4/18 3:11:40

TensorFlow 2.5-gpu与PyTorch 1.8-gpu安装指南

深度学习双雄&#xff1a;TensorFlow 2.5-gpu 与 PyTorch 1.8-gpu 实战部署指南 在现代 AI 工程实践中&#xff0c;一个稳定、可复现的 GPU 环境往往是项目成败的关键。尽管新版本框架层出不穷&#xff0c;但在企业级系统维护和科研成果落地中&#xff0c;TensorFlow 2.5-gpu …

作者头像 李华
网站建设 2026/4/17 13:09:21

深度学习图像处理(3)----二阶段目标检测

文章目录前言1.深度学习2.two-stage 和one-stage 检测算法一.候选框的提取1. 暴力遍历2.在穷举暴力法的基础上&#xff0c;进行一些剪枝操作&#xff1a;二.选择性搜索&#xff08;SS Selective Search&#xff09;1.去掉冗余的候选区域2.自底向上合并3.合并方法4. 计算相似度的…

作者头像 李华
网站建设 2026/4/15 13:12:25

LobeChat能否实现OCR文字识别集成?图像信息提取路径

LobeChat 与 OCR 集成&#xff1a;让图像“开口说话”的技术路径 在智能对话系统日益普及的今天&#xff0c;用户早已不满足于“打字提问、机器回复”的单一交互模式。越来越多的应用场景要求 AI 能“看懂”图片——比如上传一张发票&#xff0c;希望助手自动提取金额和商户信息…

作者头像 李华