欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 【高级编程】泛型的定义(接口 类 方法)无界通配符 <?> 上界下界通配符 <? extends T><? super T>

【高级编程】泛型的定义(接口 类 方法)无界通配符 <?> 上界下界通配符 <? extends T><? super T>

2024/10/25 18:57:20 来源:https://blog.csdn.net/m0_66584716/article/details/142523999  浏览:    关键词:【高级编程】泛型的定义(接口 类 方法)无界通配符 <?> 上界下界通配符 <? extends T><? super T>

泛型的定义

定义1:泛型接口

一种具有类型参数的接口。这意味着当实现这个接口的时候,必须指定具体的类型参数。这样,该接口中的所有抽象方法都可以操作指定的数据类型。

public interface Container<T> {public abstract void add(T item);public abstract T get(int index);
}

T是一个类型参数,代表某种未知的数据类型。任何实现Container接口的类都需要提供T的具体类型,比如StringInteger等。

在Java泛型中,类型参数通常是单个大写字母,它们代表的是未知的数据类型。这些字母的选择并不是强制性的,但有一些常见的惯例来帮助开发者快速理解代码的意图。

下面是几个常用的类型参数及其含义:

  • T - Type(类型): 这是最常用的类型参数,通常用来表示“任意类型”。当没有更具体的含义时,可以使用T
  • E - Element(元素): 通常用于表示集合中的元素类型,如列表或数组中的元素。例如,在java.util.List<E>接口中,E就代表列表中的元素类型。
  • K - Key(键): 一般用于映射(Map)接口中,代表键的类型。例如,在java.util.Map<K, V>接口中,K就是键的类型。
  • V - Value(值): 同样常用于映射(Map)接口中,代表与键关联的值的类型。在java.util.Map<K, V>中,V就是值的类型。
  • N - Number(数字): 有时用来指代数值类型,比如IntegerDouble等。

接下来,创建一个实现了这个接口的具体类StringContainer,专门用于存储字符串

public class StringContainer implements Container<String> {private List<String> items = new ArrayList<>();@Overridepublic void add(String item) {items.add(item);}@Overridepublic String get(int index) {return items.get(index);}
}

定义2:泛型类

包含一个或多个类型参数的类。创建该类的对象时,需要为这些类型参数提供具体的数据类型。这使得类能够以一种类型安全的方式处理不同类型的数据。

public class Box<T> {private T content;public void setContent(T content) {this.content = content;}public T getContent() {return content;}
}

Box类可以用作存放任何类型对象的容器。例如:可以创建Box<String>或者Box<Integer>来分别存放字符串和整数。

public static void main(String[] args) {// 创建一个可以存放整数的盒子Box<Integer> intBox = new Box<>();intBox.setContent(42);System.out.println(intBox.getContent());// 创建一个可以存放字符串的盒子Box<String> stringBox = new Box<>();stringBox.setContent("Hello, world!");System.out.println(stringBox.getContent());
}

定义3:泛型方法

在方法级别上使用的泛型。它们可以在非泛型类中定义,并且可以有自己独立于类本身的类型参数。泛型方法的好处是可以在不修改整个类的情况下添加泛型功能。

public class Utils {public static <E> void printArray(E[] elements) {for (E element : elements) {System.out.println(element);}}
}

工具类Utils 中包含了一个泛型方法printArray,该方法可以打印出数组中的所有元素。

public static void main(String[] args) {Integer[] intArray = {1, 2, 3, 4, 5};String[] strArray = {"a", "b", "c", "d"};// 打印整数数组Utils.printArray(intArray);// 打印字符串数组Utils.printArray(strArray);
}

泛型方法 printArray 能够处理不同类型数组的打印工作。

通配符(wildcards)

通配符提供了一种方式来指定类型参数的未知部分。通配符使得泛型更加灵活,同时保持了类型安全。Java中的通配符主要有三种形式:

通配符符号表示描述应用场景
无界通配符<?>表示可以是任何类型通常用于当不关心具体的类型是什么,但需要保证类型安全性的情况
上界通配符<? extends T>表示类型必须是TT的子类适用于读取操作(如获取元素)
下界通配符<? super T>表示类型必须是TT的父类适用于写入操作(如添加元素)限制:不允许添加新的元素,因为不确定具体的类型。

<?>

限制:不能向使用无界通配符声明的集合中添加非 null 元素,因为编译器不知道集合的确切类型。

List<?> list = new ArrayList<String>();
// list.add("test"); // 编译错误
list.add(null);  // 可以添加 null

<? extends T>

限制:不允许添加新的元素,因为不确定具体的类型。

List<? extends Number> numbers = new ArrayList<Integer>();  // Integer 是 Number 的子类
Number num = numbers.get(0);  // 可以获取元素
// numbers.add(1);  // 编译错误,不能添加元素

<? super T>

限制:从这样的集合中取出的数据只能视为 Object 类型。

List<? super Integer> integers = new ArrayList<Number>();  // Number 是 Integer 的父类
integers.add(1);  // 可以添加元素
// Integer i = integers.get(0);  // 编译错误,只能获取 Object 类型
Object obj = integers.get(0);  // 获取到的是 Object 类型

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com