2026/6/20 1:57:11
网站建设
项目流程
展示型企业网站,网站的布局怎么做,搜索引擎调词软件,网站销售系统泛型 (Generics)
定义
泛型#xff1a;允许在定义类、接口和方法时使用类型参数#xff0c;从而在编译时捕获类型错误#xff0c;提高代码的类型安全性和复用性。
主要用途
类型安全#xff1a;避免类型转换错误#xff0c;编译时检查类型安全。代码复用#xff1a;通过泛…泛型 (Generics)定义泛型允许在定义类、接口和方法时使用类型参数从而在编译时捕获类型错误提高代码的类型安全性和复用性。主要用途类型安全避免类型转换错误编译时检查类型安全。代码复用通过泛型可以编写通用的类和方法适用于多种数据类型。消除强制类型转换在使用泛型时编译器会自动进行类型转换减少代码中的强制类型转换。泛型的基本语法标记符T 是类型参数通常使用 T、E、K、V 等字母来表示不同类型。 使用时必须指定 T 的具体类型例如BoxString box new Box(); E - Element (在集合中使用因为集合中存放的是元素) T - TypeJava 类 K - Key键 V - Value值 N - Number数值类型 /*注意标记符只是起一个提示作用并不代表你写了E就只能传入集合类型这些字母其实可以自己定义。 所有字母的作用都是一样的代表不确定类型*/ //比如 public static void main(String[] args) { add(1); add(2); add(new int[]{1, 2, 3}); } public static A void add(A a) { System.out.println(a); }泛型类public class BoxT { private T item; public void set(T item) { this.item item; } public T get() { return item; } } public class Main { public static void main(String[] args) { BoxInteger integerBox new Box(); integerBox.set(10); System.out.println(integerBox.get()); // 输出: 10 BoxString stringBox new Box(); stringBox.set(Hello); System.out.println(stringBox.get()); // 输出: Hello } }泛型接口public interface ContainerT { void add(T item); T get(int index); } public class ArrayListContainerT implements ContainerT { private ListT list new ArrayList(); Override public void add(T item) { list.add(item); } Override public T get(int index) { return list.get(index); } } public class Main { public static void main(String[] args) { ContainerString container new ArrayListContainer(); container.add(Hello); container.add(World); System.out.println(container.get(0)); // 输出: Hello System.out.println(container.get(1)); // 输出: World } }泛型方法public class Util { public static T void printArray(T[] array) { for (T item : array) { System.out.println(item); } } } public class Main { public static void main(String[] args) { Integer[] intArray {1, 2, 3}; Util.printArray(intArray); // 输出: 1, 2, 3 String[] stringArray {Hello, World}; Util.printArray(stringArray); // 输出: Hello, World } }泛型的边界上界extends定义表示类型参数是某个特定类型的子类型。用途用于限制泛型参数的类型范围确保类型安全。public class Test {//限制T的类型必须是继承自Number类型的所以我们传入的类型只能是Number的子类//及java中值类型所对应的引用类型 int-Integerpublic static void printList(List list) {for (Number num : list) {System.out.println(num);}}public static void main(String[] args) { ListInteger intList Arrays.asList(1, 2, 3); printList(intList); // 输出: 1, 2, 3 ListDouble doubleList Arrays.asList(1.1, 2.2, 3.3); printList(doubleList); // 输出: 1.1, 2.2, 3.3 }}下界 (super)定义表示类型参数是某个特定类型的父类型。用途用于限制泛型参数的类型范围确保类型安全。错误写法public static T super Integer void printList(ListT list) { for (Number num : list) { System.out.println(num); } } public static void main(String[] args) { ListInteger intList Arrays.asList(1, 2, 3); printList(intList); // 输出: 1, 2, 3 ListDouble doubleList Arrays.asList(1.1, 2.2, 3.3); printList(doubleList); // 输出: 1.1, 2.2, 3.3 } /* 在Java中泛型的类型参数不能使用super关键字来定义下界。正确的语法是使用extends关键字来定义上界或者在方法参数中使用通配符加上super关键字来定义下界。 我们的代码尝试定义了一个泛型方法addNumbers该方法接受一个列表参数列表中的元素类型为T并且T应该是Integer的超类型即可以是Integer本身或它的父类 但是T super Integer这种写法是不正确的。如果你想表达这个意思应该使用通配符? super Integer来代替。 */对于下界lower bound的定义Java 泛型只支持使用通配符? super来表示。具体来说? super T表示类型T及其所有父类型。通配符表示未知类型适用于参数未知的通用集合。java复制代码public static void printList(List? list) { for (Object obj : list) { System.out.println(obj); } }所以下界的正确写法为public static void addNumbers(List? super Integer list) { list.add(1); list.add(2); list.add(3); } public static void main(String[] args) { ListInteger intList new ArrayList(); addNumbers(intList); // 向intList中添加1, 2, 3 ListNumber numberList new ArrayList(); addNumbers(numberList); // 向numberList中添加1, 2, 3 ListObject objectList new ArrayList(); addNumbers(objectList); // 向objectList中添加1, 2, 3 }上界通配符写法public static void printList(List? extends Number list) { for (Number num : list) { System.out.println(num); } } public static void main(String[] args) { ListInteger intList Arrays.asList(1, 2, 3); printList(intList); // 输出: 1, 2, 3 ListDouble doubleList Arrays.asList(1.1, 2.2, 3.3); printList(doubleList); // 输出: 1.1, 2.2, 3.3 }5、类型擦除 (Type Erasure)类型擦除Java 编译器会在编译时将泛型参数擦除为Object或其边界类型。编译后的class文件代码public static T extends Number void printList(ListT list) { Iterator var1 list.iterator(); while(var1.hasNext()) { Number num (Number)var1.next();//将T类型擦除为Number类型 System.out.println(num); } } public static void main(String[] args) { ListInteger intList Arrays.asList(1, 2, 3); printList(intList); ListDouble doubleList Arrays.asList(1.1, 2.2, 3.3); printList(doubleList); }类型擦除的限制无法创建泛型类型实例例如T obj new T();。无法使用instanceof检测泛型类型。无法定义泛型数组例如T[] array new T[10];。6、泛型方法与泛型类的区别泛型方法可以定义在任何类中作用范围为该方法。泛型类类型参数定义在类名后整个类中有效。7、泛型的常见应用场景集合框架如ListT、MapK, V等提升了集合的类型安全性。通用算法对任意类型数据执行的通用算法如排序和查找。实用工具类如OptionalT和FutureT等用于特定类型的操作。