主页 > 开源代码  > 

Java泛型(Generics)详解与使用

Java泛型(Generics)详解与使用
一、什么是 Java 泛型?

泛型(Generics)是 Java 1.5 引入的一项重要特性,主要用于 类型参数化,允许在类、接口和方法定义时使用 类型参数(Type Parameter),从而提高代码的复用性、类型安全性和可读性。


二、为什么需要泛型? 1. 解决类型安全问题

在没有泛型的时代,集合(如 ArrayList)存储的是 Object 类型,容易发生类型转换异常。

import java.util.ArrayList; public class WithoutGenerics { public static void main(String[] args) { ArrayList list = new ArrayList(); // 没有指定类型 list.add("Hello"); list.add(100); // 这里插入了一个整数 for (Object obj : list) { // 需要强制转换,否则无法使用 String 方法 String str = (String) obj; System.out.println(str.toUpperCase()); // 运行时可能报 ClassCastException } } }

运行时会抛出 ClassCastException,因为 100 不能转换为 String。


2. 使用泛型后,编译时即可发现错误 import java.util.ArrayList; public class WithGenerics { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); // 指定类型为 String list.add("Hello"); // list.add(100); // 编译时直接报错,避免了运行时异常 for (String str : list) { System.out.println(str.toUpperCase()); } } } 类型安全:只能存储 String,避免了 ClassCastException。可读性好:不需要强制类型转换。
三、泛型的基本用法 1. 泛型类

泛型类在定义时,使用 类型参数(T) 来表示类中可以使用的类型。

// 定义一个泛型类 class Box<T> { private T item; public void setItem(T item) { this.item = item; } public T getItem() { return item; } } public class GenericClassExample { public static void main(String[] args) { Box<String> stringBox = new Box<>(); // 指定 T 为 String stringBox.setItem("Hello"); System.out.println(stringBox.getItem()); Box<Integer> intBox = new Box<>(); // 指定 T 为 Integer intBox.setItem(100); System.out.println(intBox.getItem()); } }

类型参数常见约定:

T(Type):表示任意类类型E(Element):集合中的元素类型K(Key):键V(Value):值
2. 泛型方法

泛型方法可以在 普通类或泛型类 中定义,方法的泛型参数只在方法内部生效。

class Util { // 泛型方法 public static <T> void print(T data) { System.out.println(data); } } public class GenericMethodExample { public static void main(String[] args) { Util.print("Hello"); Util.print(123); Util.print(45.6); } } 需要声明在方法返回值之前泛型方法可以独立于类的泛型类型
3. 泛型接口

泛型接口通常用于 定义通用的操作,如数据存储、服务层 API。

// 定义泛型接口 interface Repository<T> { void save(T data); T get(); } // 实现泛型接口 class StringRepository implements Repository<String> { private String data; @Override public void save(String data) { this.data = data; } @Override public String get() { return data; } } public class GenericInterfaceExample { public static void main(String[] args) { Repository<String> repo = new StringRepository(); repo.save("Hello"); System.out.println(repo.get()); } }

也可以使用 泛型类 实现泛型接口:

class GenericRepository<T> implements Repository<T> { private T data; @Override public void save(T data) { this.data = data; } @Override public T get() { return data; } }
四、泛型的高级用法 1. 泛型的通配符

通配符 ? 代表不确定的类型,主要用于:

限定方法参数,使其接受不同的泛型类型。保证类型安全,避免强制转换。 (1)? extends T 上界通配符

限制为 T 及其子类,适用于只 读取数据 的场景。

import java.util.List; public class WildcardExample { public static void printNumbers(List<? extends Number> list) { for (Number n : list) { System.out.println(n); } } public static void main(String[] args) { List<Integer> intList = List.of(1, 2, 3); List<Double> doubleList = List.of(1.1, 2.2, 3.3); printNumbers(intList); printNumbers(doubleList); } } 允许 Integer 和 Double 作为 Number 的子类传入。不能往 list 里添加元素,否则会引发 编译错误,因为 ? extends Number 可能是 Integer 或 Double,不确定具体类型。 (2)? super T 下界通配符

限制为 T 及其 父类,适用于 写入数据 的场景。

import java.util.List; import java.util.ArrayList; public class SuperWildcardExample { public static void addNumbers(List<? super Integer> list) { list.add(10); list.add(20); } public static void main(String[] args) { List<Number> numberList = new ArrayList<>(); addNumbers(numberList); System.out.println(numberList); } } 允许 Integer 及其父类(如 Number)的 List 作为参数。可以往 list 里添加 Integer 类型的元素。
2. 泛型擦除(Type Erasure)

Java 的泛型是 编译时 作用的,编译后会进行 类型擦除,即所有泛型参数都会被 替换为 Object(或其上界类型)。

class Box<T> { private T item; public void setItem(T item) { this.item = item; } public T getItem() { return item; } }

编译后等价于:

class Box { private Object item; public void setItem(Object item) { this.item = item; } public Object getItem() { return item; } }

影响:

不能直接创建泛型数组:T[] array = new T[10]; // 编译错误不能使用 instanceof 检测泛型类型:if (obj instanceof Box<String>) // 编译错误
总结 特性说明泛型类通过 <T> 定义,可以使用不同类型创建实例泛型方法方法独立于类的泛型,可以使用不同类型参数泛型接口定义通用接口,支持泛型类实现通配符 ?? extends T 适用于读取,? super T 适用于写入泛型擦除编译后泛型类型被擦除,限制了某些操作

注🚀:泛型是 Java 类型安全 和 代码复用 的重要特性,熟练掌握可以大幅提升开发效率!

标签:

Java泛型(Generics)详解与使用由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java泛型(Generics)详解与使用