1. 泛型类。在类名后面声明泛型变量。
class GenericMap<T extends Number, E extends Date> extends HashMap<T, List<E>> {
....
}
new GenericMap<Integer, Time>()的时候才最终绑定T(Integer)和E(Time)。所以这个map的get方法实际上变成了
public List<Time> get(Integer key) {
return super.get(key);
}
2. 泛型方法。在返回值之前申明泛型变量。
public static <T, E extends Number> int getSize(Map<T, List<E>> map) {
return map.size();
}
综上所述,泛型变量只能在类名后面或方法的返回值前面声明。注意泛型变量可以不加任何约束<T>,或者只能用上限<T extends Number>,不能用下限,后面将提到。
3. Java的泛型并不能很好的支持多态
Example: List<Number> list = new ArrayList<Integer>(); // 编译错误
Example:
public static void testGeneric1(List<Number> list) {
// ...
}
...
testGeneric1(new ArrayList<Integer>()); // 编译错误
...
这时候必须用List<? extends Number>来代替List<Number>。这就要使用通配符(?)了
4. wildcast泛型通配符? 泛型上限和下限 bound
上面例子提到用<? extends Number>来解决编译错误,这是用到了泛型的上限,同理还可以定义下限,比如<? super Number>.
上边界限定通配符 <? extends T>,T是类型参数上界
public void upperBound1(List<? extends Number> list) {
Number number = list.get(0); // 可见上限主要是用于从容器中往外取元素的,取出的内容都可视为其上限类型T
list.add(number); // 这句话无法通过编译,因为在运行时,传入的参数可能是List<Integer>
}
如果非要写的话,所以这个方法可以这么写
public <T extends Number> void upperBound2(List<T> list) {
Number number = list.get(0);
list.add((T)number); // 除非作强制类型转换,否则父类型是无法放入字类型容器中的。
}
下边界限定通配符 <? super T>,T是类型参数的下界
public void lowerBound1(List<? super Number> list) {
Number number = list.get(0); // 编译错误。因为在运行时,传入的参数可能是List<Object>,须作强制类型转换
list.add(number); // 可见下限主要是用于往容器中放 下限类型T 的对象
}
无边界通配符<?>, 不做任何限制
不能读取(读出的类型为?,因此无法使用),也不能写入,只能用跟通配类型无关的一些API
public void unBound(List<?> list) {
list.size();
}
PECS原则:
如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)
如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)
public <T> void copy(List<? super T> dest, List<? extends T> src)
{
for (int i=0; i<src.size(); i++) {
dest.set(i,src.get(i));
}
}
综上所述,泛型通配符只能用在变量声明(定义)或方法的形参声明上。泛型通配符可以不加任何约束<?>,或者用上限<? extends T>或下限<? super T>。
5. <?>和<Object>的区别
List<?> list 表示 list 是持有某种特定类型的 List,但是不知道具体是哪种类型。那么我们可以向其中添加对象吗?当然不可以,因为并不知道实际是哪种类型,所以不能添加任何类型,这是不安全的。而单独的 List list ,也就是没有传入泛型参数,表示这个 list 持有的元素的类型是 Object,因此可以添加任何类型的对象,只不过编译器会有警告信息。
相关推荐
7. **泛型(Generics)**: - 在Java中,树节点可能需要存储各种类型的数据,因此,使用泛型可以使树节点类更加灵活,能够适应多种数据类型。 8. **递归**: - 构建树形结构和执行逐级汇总通常涉及递归操作。递归...
首先,从【标题】:“java知识点汇总” 和【描述】:“内容较杂,有java初中高级知识点,也有Java web架构及原理”来看,涉及的内容包括了Java的序列化与反序列化、IO流的基础知识、多态的概念、泛型的应用、反射...
JDK 1.5引入的泛型(Generics)是Java语言的一个重要里程碑,极大地提升了代码的可读性和类型安全性。 #### 2. 内存管理与Java特性 - **内存**: Java的内存管理机制包括堆(Heap)和栈(Stack)。堆用于存储对象...
6. **泛型(Generics)**:泛型提供了一种在编译时检查类型安全的方法,允许在容器类中存储特定类型的元素。 7. **多态(Polymorphism)**:多态是指同一个接口,使用不同的实例而产生不同的效果。它是面向对象的三...
泛型(Generics)在Java中提供了一种类型安全的解决方案,允许开发者在编译时指定容器中元素的具体类型,从而避免了运行时类型转换错误。其本质在于类型参数化,即使用类型参数代替具体的类型,实现代码的复用性和...
12. 泛型(Generics):泛型是 Java 5 的新特性,用于提供编译时类型安全和提高代码复用。泛型允许在类、接口和方法中使用类型参数,限制了插入错误类型的对象。 以上只是 Java 词汇表中的一部分内容,Java 作为...
Java中的多态主要体现在方法重写(Override)和泛型(Generics)。 2. **String不是基本数据类型**: - Java的基本数据类型包括int、char等,而String是对象,属于引用类型。它不可变,一旦创建就不能修改。 - **...
【Java程序员面试题集常见题目经典精选汇总大全(1-50)】 1. 面向对象的特征 面向对象的四个主要特征是抽象、继承、封装和多态性。 - 抽象:抽象是将一组具有相同特征的对象提炼成类的过程,分为数据抽象和行为...
11. **泛型** (Generics):允许在类、接口和方法中使用类型参数,提高代码的复用性和安全性。 12. **并发编程** (Concurrency):Java提供了线程(Thread)、同步(Synchronized)、并发工具类(如`ExecutorService`...
20. **泛型(Generics)**:在类、接口和方法中引入类型参数,以增强类型安全性和代码复用。如 `<T> List<T> myList = new ArrayList();` 以上只是Java编程中的一小部分常用词汇,通过深入学习和实践,你会逐渐熟悉...
#### 四、泛型(Generics) 泛型提供了一种类型安全的方法来指定容器中元素的类型,提高了程序的灵活性和可重用性。 **特点:** - 类型参数允许编译时检查类型安全,并且所有的类型信息在运行时都会被擦除。 - ...
- 泛型(Generics):允许创建可以处理多种类型的函数或类型。 - 可选链(Optional Chaining):`?.`操作符用于访问可选值的属性或方法,如果可选值为nil则不执行后续操作。 - 值类型与引用类型:Swift中的结构体...