`
刘琛颖
  • 浏览: 49992 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

深入了解Java泛型(二) -- 泛型列表与数组

阅读更多
记得以前面试的时候曾被问过一个问题:数组和List的区别是什么?当时答的无非就是效率,容量固定,List不能存基本类型等等。当Java发展到了1.5之后,出现了泛型版本的List,又为这个问题的解答加入了一笔。下面就来讲一下与这个话题相关的内容。

1. 数组的协变性。
数组的协变性(covariant)是指如果类Base是类Sub的基类,那么Base[]就是Sub[]的基类。而泛型是不可变的(invariant),List<Base>不会是List<Sub>的基类,更不会是它的子类。数组的协变性可能会导致一些错误,比如下面的代码:

Java代码
	public static void main(String[] args) {
		Object[] array = new String[10];
		array[0] = 10;
	}


它是可以编译通过的,因为数组是协变的,Object[]类型的引用可以指向一个String[]类型的对象。但是运行的时候是会报出如下异常的:

Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer

原因就像呼吸一样简单。

但是对于泛型就不会出现这种情况了:

Java代码
	public static void main(String[] args) {
		List<Object> list = new ArrayList<String>();
		list.add(10);
	}


这段代码连编译都不能通过。

2. 数组的具体化。
第二个要讲的问题是数组是具体化的(reified),而泛型在运行时是被擦除的(erasure)。这句话的意思是数组是在运行时才去判断数组元素的类型约束,而泛型正好相反,在运行时,泛型的类型信息是会被擦除的,只有编译的时候才会对类型进行强化。

所以上面的例子中,数组的方法会在运行时报出ArrayStoreException,而泛型根本无法通过编译。

3. 泛型与数组的结合。
这个问题的标题有些误导,其实泛型与数组根本没有任何结合的可能性。List<E>[]、List<Integer>[]、或者E[]的写法都是错误的。因为这些方法无法提供类型的安全性。我们来分别举2个例子来说明它们会导致的错误。

Java代码
	public void testMethod1() {
		List<Integer>[] array = new List<Integer>[10];
		List<String> list = new ArrayList<String>();
		Object[] objs = array;
		objs[0] = list;
	}


这段代码假设array这个泛型数组是可以被创建的,那么它就可以被Object[]类型的变量引用,进而导致了array中的元素变成了List<String>类型了,发生了类型错误。

第二个例子是关于类型参数数组的:

Java代码
	public <E> void testMethod2(E e) {
		E[] array = new E[10];
		Object[] objs = array;
		objs[0] = e;
		objs[1] = "string";
		objs[2] = 10;
		objs[2] = true;
	}


与上边的那个例子相似,array可以放入任何类型的元素了,这个是很不安全的。

这里有一个例外的情况可以说一下,无限制通配符类型的泛型是可以创建泛型数组的。

Java代码
List<?>[] listArray = new List<?>[10];

分享到:
评论

相关推荐

    java泛型数组

    ### Java 泛型数组的理解与应用 #### 一、引言 Java 泛型是 Java SE 5.0 引入的新特性,它允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。然而,在 Java 中创建泛型数组却...

    java不支持创建泛型数组(1)

    在Java编程语言中,"java不支持创建泛型数组(1)"这个标题揭示了一个重要的概念,即Java不直接允许我们创建带有类型参数的泛型数组。这是因为Java的泛型是类型擦除的,这意味着在编译后,所有的泛型信息都会被移除,...

    Java 泛型总结(二):泛型与数组

    Java 泛型总结(二):泛型与数组 Java 中泛型数组的关系确实有些复杂,不允许直接创建泛型数组,本文将分析其中的原因,并总结一些创建泛型数组的方式。 首先,让我们看看数组和泛型的关系。数组相比于 Java ...

    实例185 - 自定义泛型化数组类

    "实例185 - 自定义泛型化数组类"是一个关于如何创建和使用自定义泛型数组类的示例,这个主题将深入探讨泛型、数组以及两者的结合。 首先,我们需要理解泛型的基本概念。泛型是Java 5引入的一个重要特性,它允许我们...

    Java泛型和集合-英文版

    由于书籍的作者是Maurice Naftalin和Philip Wadler,这两人都是在泛型和集合方面有着深入研究的专家,因此书中内容被期待会是权威和详尽的,为读者提供全面的Java泛型和集合知识。本书适合有一定Java基础并希望深入...

    java泛型技术之发展

    本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展历程** - **早期版本的局限**:在Java泛型出现之前,程序员通常使用Object作为容器类(如ArrayList、HashMap等)的默认类型...

    Java泛型应用实例

    配合博主的博客文章,你可以更深入地了解泛型在实际项目中的应用,包括但不限于类型安全的容器、泛型与反射的交互、以及泛型在并发编程中的作用等。通过实践这些实例,你将能够更好地掌握Java泛型的精髓,提高编程...

    Java泛型_Java中的泛型结构_

    Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...

    关于java基础的泛型的练习

    Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全性和可读性。泛型在编程中的应用广泛,特别是在集合框架中,使得我们可以在编译时就检查类型,避免了不必要的类型转换,并且提高了代码的...

    泛型自定义数组大小

    - **数组的排序**:如果需要对泛型数组进行排序,可以利用Java的`Collections.sort()`方法(对于集合)或`Arrays.sort()`方法(对于数组),但需要注意,数组的元素必须实现了`Comparable`接口或提供自定义的`...

    java 泛型的使用 详细讲解

    ### Java泛型的使用详细讲解 #### 一、引言 在Java开发中,泛型是一种重要的语言特性,它能够帮助开发者在不增加代码量的情况下处理多种数据类型,同时还能保持代码的清晰度和可读性。本文将详细介绍Java泛型的...

    java泛型源码-Java-Generics-Tutorial:教程的源代码

    java泛型源码Java泛型用法 步骤1 原始类型有问题。 第2步 使用泛型类型。 第三步 车库和车辆。 原始类型。 第四步 首先尝试生成车库。 木星在我的车库里。 第5步 泛型上限。 第6步 TripleGarage 步骤7 试图使用泛型...

    java 泛型入门 实例

    本篇文章将带你入门Java泛型,通过实例深入理解其核心概念。 1. **泛型的基本概念** - 泛型是一种允许在定义类、接口和方法时使用类型参数的机制。这使得代码可以在编译时期检查类型,避免了不必要的类型转换,并...

    Java泛型总结(2)进阶篇

    在本文中,我们将深入探讨Java泛型的进阶概念,包括通配符、边界、类型擦除以及在实际开发中的应用。 1. 通配符 通配符在Java泛型中扮演着重要角色,它允许我们处理多种类型的参数。例如,`&lt;?&gt;` 表示未知类型,...

    Java泛型使用详细分析.pdf

    Java 泛型使用详细分析 Java 泛型是 Java 语言中的一种类型系统特性,允许开发者在编译期检查类型安全,以避免在运行时出现类型相关的错误。在本文中,我们将详细介绍 Java 泛型的使用方法和实现原理。 一、泛型的...

    java泛型指南 经典

    ### Java泛型指南经典知识点解析 #### 一、引言 Java 1.5 版本引入了一系列重要的语言特性,其中“泛型”是其中一项关键特性。泛型的引入极大地提高了 Java 语言的类型安全性和代码重用性。本文档旨在深入探讨 ...

Global site tag (gtag.js) - Google Analytics