1 父类是个泛型类,子类继承父类,如果不指定父类的泛型类型或者没有重新声明一个泛型,那么子类讲不是一个泛型类
public class Parent<T> { } public class Son extends Parent { }
下面这样写是会报错的
Son<Integer> song = new Son<Integer>();
2 类型通配符
2.1 <? extends xx>
Number obj = new Integer(123); List<Integer> integerList = new ArrayList<>(); List<Number> numberList = integerList;
java对象,父类型可以引用所有的子类实现,如上第一行代码Number引用类型可以引用Integer对象
而List<Number>和List<Integer>没有任何上下级关系,List<Number>是不能引用List<Integer>的,上面的最后一行代码会报错,而数组确可以,因为数组是协变的,如下代码是合法的
Integer[] integerArry = new Integer[1]; Number[] numberArry = integerArry;
类似Number引用Integer,如果我想用List<Number>引用List<Integer>怎么办?
List<? extends Number>就是用来解决这个问题的,除了Integer,任何继承自Number的类都可以引用。
通过类型通配符List<? extends Number>引用会产生副作用:
(1)可以get列表中的值,并且用Object或Number来引用这个值。
Object好理解,它可以引用任何类型
由于List<? extends Number>所引用的列表中的元素类型一定是Number的子类型,所有可以用Number引用也好理解
(2)不能set除了null以外的任何值
因为List<? extends Number>可以引用任何Number子类型的List,具体是哪一个,无法得知,也是就是不知道List中的原始是什么类型(只知道是Number的子类型),所以也就无法set元素。
说了半天,List<? extends Number>究竟是用来解决什么问题的?难道仅仅是引用更多类型参数的List吗?或者说,引用更多类型参数的List可以达到什么目的?假设有这样一个场景,提供一个方法,方法的入参是List<Number>,这个方法的逻辑就是把这个列表中的值取出来,执行某些操作。取出元素后,通过Number来引用元素,然后执行某些操作,代码完全是针对Number类型来写的。理论上针对Number类型写的代码,同样适用于Number的所有子类(面向接口编程),所以泛型类型是Number子类的List,也可以在这个方法中得到正确的处理。但是我们怎么才能支持,所有泛型类型是Number子类的list可以传递到这个方法中,List<Number>肯定不支持,List<? extends Number>正好可以满足这个需求。请注意,仅仅是把列表中的元素取出来,如果要往这个列表中set元素,这是List<? super Number>所要解决的问题。
相关推荐
在“java泛型的内部原理及更深应用”这个主题中,我们将深入探讨以下几个关键知识点: 1. **类型擦除**:Java泛型的主要特点是类型擦除。这意味着在编译完成后,所有的泛型信息都会被擦除,替换为Object或者其他...
在创建泛型对象时,需要注意以下几点: 1. **显式指定类型**:当创建泛型对象时,最好明确指定类型参数`T`的具体类型,以便编译器能够进行类型检查。例如: ```java Pair<String> pair = new Pair("a", "b"); ``...
通过上述讨论,我们可以得出以下几点结论: 1. **泛型数组的创建**:在 Java 中,直接创建泛型数组是不可能的,而应当采用 `Array.newInstance` 或其他替代方案。 2. **类型擦除的影响**:Java 泛型在运行时会被擦除...
感谢所有为Java泛型做出贡献的人们,包括设计者、实现者以及提供反馈和支持的社区成员。泛型是Java语言的一个重要特性,极大地提高了代码的质量和可维护性。 以上就是基于给定文件信息对Java 1.5泛型指南的主要知识...
在使用泛型时需要注意以下几点: 1. **定义泛型类**:在定义泛型类时,需要在类名后面的尖括号 `和 `>` 之间定义类型参数。例如 `class JavaGenerics, V>`,这里的 `K` 和 `V` 代表类型而不是具体的值。 2. **...
书中可能涵盖了以下几个关键点: 1. **泛型的基本用法**:如何声明和使用泛型类、泛型方法以及通配符(如)。 2. **泛型的边界**:如何限制类型参数的范围,如`List<? extends Number>`只允许Number或其子类。 3. *...
在这个"学士后Java集合框架和泛型课后习题答案"中,我们可以深入理解以下几个关键知识点: 1. **集合接口**:List、Set、Map是Java集合框架的三大接口。List接口代表有序且可重复的元素序列,如ArrayList和...
在实际开发中,继承泛型类有以下几个关键点需要注意: 1. **类型擦除**:Java的泛型在编译后会被擦除,也就是说在运行时,泛型信息不会存在。因此,泛型主要是在编译时提供类型检查,而非运行时。 2. **类型约束**...
在使用泛型时,有几点需要注意: 1. **类型擦除**:Java的泛型在编译后会被擦除,因此泛型不会在运行时存在。这意味着无法在运行时检查泛型类型,所有有关泛型的检查都在编译时完成。 2. **通配符**:在需要与多种...
在使用泛型时,需要注意以下几点: 1. 泛型的类型参数不能是基本类型,例如int、double等。 2. 泛型的类型参数不能是数组类型,例如String[]等。 3. 泛型的类型参数不能是原始类型,例如List等。 4. 泛型的类型参数...
在使用泛型时,有以下几点需要注意: 1. 类型参数的声明:在定义泛型类或接口时,使用尖括号`<>`来声明类型参数,例如`class Box<T>`,其中`T`是类型参数,代表某种未知类型。 2. 泛型约束:可以为类型参数设定...
虽然Java泛型在运行时会被擦除,无法直接获取到类型参数的实际类型(即`T.class`),但可以通过反射机制获取到类型信息。下面是一个典型的例子: ```java public abstract class BaseHibernateEntityDao<T> extends...
在《java-generic.rar》压缩包中包含的《java generic.pdf》文件,很可能是详细阐述了以下几个关于Java泛型的核心知识点: 1. **类型参数化**:泛型的核心在于类型参数化,这使得我们可以在定义类、接口和方法时...
本知识点主要关注于Map接口的介绍和几种Map实现类的详解。 首先,Map是一个键值对集合,其中每个键映射到一个值,一个Map不能包含重复的键,每个键最多只能映射到一个值。Map接口中提供了许多方法,例如put方法用于...
泛型的使用主要有以下几点: 1. **类型参数化**:在类、接口或方法声明中使用尖括号 `<T>` 表示类型参数,其中 `T` 可以是任意字母或标识符。 2. **通配符**:如 `?`,用于表示任意类型,或者限制类型(如 `? ...
"Java高级知识点详解系列"聚焦于几个核心领域:Java内存管理、泛型以及反射。这些概念在实际开发中至关重要,理解它们能够帮助开发者写出更高效、更灵活且更易于维护的代码。 1. **Java内存**:Java内存主要涉及堆...
使用泛型时要注意以下几点: - 类声明的泛型需要通过实例化类来约束具体的类型,如`TypeA<String> typeA = new TypeA();` - 如果没有指定泛型的实际类型,那么默认的类型将是`Object`,但这是不推荐的做法。 - 在类...