《剖析Java泛型通配符》
Iteye的编辑器,是我见过最垃圾的编辑器
使用泛型的目的有2个,首先是保证了安全性,其次是表述性方面的优势,毕竟对于一些语义上的错误(比如:类型转换),应该尽可能在编译期就发现。
泛型相信大家都不会陌生,我们在Java5后使用集合API时,基本上时时刻刻都是在和泛型打着交道,那么笔者便不再对泛型的一些基础语法进行介绍,直接进入本章主题,泛型的无限制通配符。
当我们在使用泛型的时候,如果不明确实际的类型参数,那么就可是使用<?>来代替,这种方式便称作无限制通配符,比如List<?>就意味着其类型参数可以是任意类型。值得注意的是,List<?>由于无法在编译期确定究竟是什么类型,因此List不能添加任何元素(除了无意义的null外),以及get操作时返回的是Object,因为编译器无法预知你需要获取的究竟是什么鬼。或许有同学会有疑问,这似乎和Object是一个尿性,那么为啥不用Object直接替代无限制通配符?这是因为实现泛型之间的父子关系,需要有一种表示未知类型的方式。
换句话说,使用List<?>的意义其实并不是很大,因为不能作为消费者(添加数据),获取数据时甚至还会丢失一些类型信息,比如:
List<?> list = new ArrayList<String>();
上述程序实例中,ArrayList<String>实际上是List<?>的派生类型,但是当我们使用get获取数据时,有可能会丢失一些类型信息,毕竟之前笔者曾经提及过,<?>由于无法确定其类型,因此返回的只能是Object。如果你无法接受,那么你可以考虑有限制的通配符类型。毕竟,相对于类型的一无所知,至少我可以明确需要满足什么样的条件,这对于后续操作起到了较大的帮助。
有限制的通配符,可以分为2种:
1、超类限定:<? super E>;
2、派生限定:<? extends E>。
如果使用超类限定,既List<? super E>,那么也就限制了类型参数只能够是E本身或者是E的超类,如下所示:
List<? super Integer> list = new ArrayList<Number>();
list.add(1);
/* 由于编译器无法确定其类型,所以返回为Object类型 */
list.get(0);
超类限定在操作上存在以下一些局限性:
1、只能做添加操作,类型参数只能够是其本身或者超类;
2、获取数据时,由于编译器并不明确其类型,所以返回的数据类型只能是Object。
接下来看看派生限定(子类限定),即List<? extends E>,那么也就限制了类型参数只能够是E本身或者是E的派生类,如下所示:
List<? extends Number> list = new ArrayList<Integer>();
/* 编译器无法确定其类型,所以无法执行添加操作 */
//list.add(1);
list.get(0);
派生限定在操作上存在以下一些局限性:
1、只能做获取操作,类型参数只能够是其本身或者派生类;
2、添加数据时,由于编译器并不明确其类型,所以不能够执行添加操作。
当然,你可能会产生疑问,有限制的通配符应该具体应用在哪一种场景下呢?参考PESC(Producer Extends,Consumer Super”)原则,当作为生产者的时候(获取操作)时,应该使用派生限定:<? extends E>,因此你不能添加数据;当作为消费者的时候(添加操作),应该使用超类限定:<? super E>;当既是消费者,同时又是生产者的时候,你就不应该再继续使用泛型通配符类型。
相关推荐
Java 中泛型通配符的使用方法示例主要介绍了 Java 中泛型通配符的使用方法,结合实例形式分析了 Java 中泛型通配符的功能、语法及在泛型类创建泛型对象中的使用方法。以下是 Java 中泛型通配符的使用方法示例的知识...
Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入,极大地增强了类型安全性和代码可读性。...对于Java泛型的例子,可以通过运行和分析压缩包中的`generic`文件来加深理解和实践。
Java泛型是Java编程语言中的一个重要特性,它在2004年随着Java SE 5.0的发布而引入。这个特性允许程序员在定义类、接口和方法时声明类型参数,从而增强了代码的类型安全性和重用性。通过使用泛型,我们可以编写更加...
除了指定具体的类型,Java泛型还支持类型通配符,如`<?>`,表示未知的类型。在某些场景下,当不需要访问具体类型信息,仅关心对象是否属于特定类型或其子类型时,类型通配符非常有用。 6. **边界限定** Java泛型...
以下是对Java泛型的详细解释: 1. **泛型类型**:泛型类型允许我们在定义类、接口或集合时引入类型参数。比如`List<String>`就是一个泛型类型,其中String是类型参数,代表了列表中的元素类型。这样,当我们将字符...
泛型是Java 5引入的一项创新特性,极大地增强了集合框架的安全性和效率。本讲解将深入探讨这两个主题,以及与之相关的枚举类型。 首先,Java集合框架包括List、Set、Queue等接口,以及ArrayList、LinkedList、...
在Java编程语言中,泛型是一种强大的特性,它...总的来说,理解和掌握Java泛型类的继承应用是提高代码质量和可维护性的关键一步。通过这个压缩包中的源码,你将有机会实践和探索这一主题,进一步提升你的Java编程技能。
Java泛型和C#泛型在处理类型安全和灵活性方面有着不同的设计哲学。本文将深入探讨Java中的类型通配符及其与C#泛型约束的对比。 首先,让我们来看看Java中的类型通配符。在Java中,类型通配符允许程序员在泛型参数中...
4. **泛型通配符** 除了指定特定类型外,还可以使用通配符`?`表示任意类型。例如,`List<?>`表示可以容纳任何类型的列表,但无法插入元素。`List<? extends Number>`则表示列表可以包含任何Number子类的实例,这在...
Java类型通配符是Java泛型系统中的一种重要机制,它允许开发者在编写泛型代码时更加灵活和安全。本文将详细介绍Java类型通配符的概念、原理和应用实战,帮助读者更好地理解和应用Java类型通配符。 一、Java类型...
泛型和通配符是Java编程中的重要概念,它们在处理类型安全和代码复用方面起着关键作用。本文将深入探讨这两个主题,并提供一些常见的面试题,帮助开发者理解和掌握这些知识点。 首先,我们来理解泛型。泛型是Java 5...
### 泛型类、通配符的使用及上下限详解 #### 1. 泛型类的概念 在Java中,泛型是一种使代码更加灵活、重用性更强且类型安全的技术。通过使用泛型,我们可以定义类型参数化的类或方法,从而避免了代码重复并且可以在...
"VarJ"是一款专门针对这种情况设计的重构工具,它的目标是帮助开发者更准确地推断和使用Java泛型中的通配符。 VarJ基于Java的源代码解析和变换框架JastAdd,这是一种基于属性文法的源代码分析和修改工具。JastAdd...
进一步深入学习还可以涉及泛型通配符、泛型继承、类型擦除等复杂主题。 对于希望深入Java程序设计的读者来说,建议查看相关的教程和参考资料,包括但不限于《Java面向对象程序设计入门与进阶教程》、《Java数据结构...
Java定义泛型方法实例分析 Java定义泛型方法是一种强大的技术,可以在编程中提供更多的灵活性和泛用性。在Java中,泛型方法可以在类、接口或方法中使用,以下是关于Java定义泛型方法的实例分析。 一、泛型方法的...
3. **通配符:**在"Pong.java"中,可能会使用到泛型通配符(如 `?` 或 `? extends SomeType`),它们用于表示对类型参数的不确定约束。通配符使得代码能处理多种类型的对象,增加了代码的灵活性。 4. **类型擦除:*...
标题中的“jd-gui.exe反编译工具解决了jad.exe无法编译泛型的问题”揭示了两个关键知识点:一是Java反编译工具JD-GUI和JAD的区别,二是关于Java泛型的编译处理。 首先,让我们来了解一下这两个反编译工具: 1. JD-...
总的来说,《夯实JAVA基本之一——泛型详解(2)》这篇博客深入剖析了Java泛型的高级特性,帮助开发者更好地理解如何在实际项目中运用泛型,提高代码质量和可维护性。通过学习这些知识点,开发者可以编写出更加高效且...
extends T>表示包括T在内的任何T的子类,下面我们详细分析一下两种通配符具体的区别。 extends List<? extends Number> foo3的通配符声明,意味着以下的赋值是合法的: // Number "extends" Number (in...