展开全部

泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以62616964757a686964616fe78988e69d8331333264656165按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

可以在集合框架(Collection framework)中看到泛型的动机。例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象。

因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为期望的类型,如下面的代码所示:

Map m = new HashMap();

m.put("key", "blarg");

String s = (String) m.get("key");

要让程序通过编译,必须将 get() 的结果强制类型转换为 String,并且希望结果真的是一个 String。但是有可能某人已经在该映射中保存了不是 String 的东西,这样的话,上面的代码将会抛出 ClassCastException。

理想情况下,您可能会得出这样一个观点,即 m 是一个 Map,它将 String 键映射到 String 值。这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。

泛型的好处

Java 语言中引入泛型是一个较大的功能增强。不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了。这带来了很多好处:

类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

Java 程序中的一种流行技术是定义这样的集合,即它的元素或键是公共类型的,比如“String 列表”或者“String 到 String 的映射”。通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误现在就可以在编译时被捕获了,而不是在运行时当作 ClassCastException 展示出来。将类型检查从运行时挪到编译时有助于您更容易找到错误,并可提高程序的可靠性。

消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

尽管减少强制类型转换可以降低使用泛型类的代码的罗嗦程度,但是声明泛型变量会带来相应的罗嗦。比较下面两个代码例子。

该代码不使用泛型:

List li = new ArrayList();

li.put(new Integer(3));

Integer i = (Integer) li.get(0);

该代码使用泛型:

List li = new ArrayList();

li.put(new Integer(3));

Integer i = li.get(0);

在简单的程序中使用一次泛型变量不会降低罗嗦程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低罗嗦程度。

潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。

由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

泛型用法的例子

泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束。考虑这个使用 Map 类的例子,其中涉及一定程度的优化,即 Map.get() 返回的结果将确实是一个 String:

Map m = new HashMap();

m.put("key", "blarg");

String s = (String) m.get("key");

如果有人已经在映射中放置了不是 String 的其他东西,上面的代码将会抛出 ClassCastException。泛型允许您表达这样的类型约束,即 m 是一个将 String 键映射到 String 值的 Map。这可以消除代码中的强制类型转换,同时获得一个附加的类型检查层,这个检查层可以防止有人将错误类型的键或值保存在集合中。

下面的代码示例展示了 JDK 5.0 中集合框架中的 Map 接口的定义的一部分:

public interface Map {

public void put(K key, V value);

public V get(K key);

}

注意该接口的两个附加物:

类型参数 K 和 V 在类级别的规格说明,表示在声明一个 Map 类型的变量时指定的类型的占位符。

在 get()、put() 和其他方法的方法签名中使用的 K 和 V。

为了赢得使用泛型的好处,必须在定义或实例化 Map 类型的变量时为 K 和 V 提供具体的值。以一种相对直观的方式做这件事:

Map m = new HashMap();

m.put("key", "blarg");

String s = m.get("key");

当使用 Map 的泛型化版本时,您不再需要将 Map.get() 的结果强制类型转换为 String,因为编译器知道 get() 将返回一个 String。

在使用泛型的版本中并没有减少键盘录入;实际上,比使用强制类型转换的版本需要做更多键入。使用泛型只是带来了附加的类型安全。因为编译器知道关于您将放进 Map 中的键和值的类型的更多信息,所以类型检查从执行时挪到了编译时,这会提高可靠性并加快开发速度。

向后兼容

在 Java 语言中引入泛型的一个重要目标就是维护向后兼容。尽管 JDK 5.0 的标准类库中的许多类,比如集合框架,都已经泛型化了,但是使用集合类(比如 HashMap 和 ArrayList)的现有代码将继续不加修改地在 JDK 5.0 中工作。当然,没有利用泛型的现有代码将不会赢得泛型的类型安全好处。

二 泛型基础

类型参数

在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数。形式类型参数与实际类型参数之间的关系类似于形式方法参数与实际方法参数之间的关系,只是类型参数表示类型,而不是表示值。

泛型类中的类型参数几乎可以用于任何可以使用类名的地方。例如,下面是 java.util.Map 接口的定义的摘录:

public interface Map {

public void put(K key, V value);

public V get(K key);

}

Map 接口是由两个类型参数化的,这两个类型是键类型 K 和值类型 V。(不使用泛型)将会接受或返回 Object 的方法现在在它们的方法签名中使用 K 或 V,指示附加的类型约束位于 Map 的规格说明之下。

当声明或者实例化一个泛型的对象时,必须指定类型参数的值:

Map map = new HashMap();

注意,在本例中,必须指定两次类型参数。一次是在声明变量 map 的类型时,另一次是在选择 HashMap 类的参数化以便可以实例化正确类型的一个实例时。

编译器在遇到一个 Map 类型的变量时,知道 K 和 V 现在被绑定为 String,因此它知道在这样的变量上调用 Map.get() 将会得到 String 类型。

除了异常类型、枚举或匿名内部类以外,任何类都可以具有类型参数。

命名类型参数

推荐的命名约定是使用大写的单个字母名称作为类型参数。这与 C++ 约定有所不同(参阅 附录 A:与 C++ 模板的比较),并反映了大多数泛型类将具有少量类型参数的假定。对于常见的泛型模式,推荐的名称是:

K —— 键,比如映射的键。

V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。

E —— 异常类。

T —— 泛型。

泛型不是协变的

关于泛型的混淆,一个常见的来源就是假设它们像数组一样是协变的。其实它们不是协变的。List 不是 List 的父类型。

如果 A 扩展 B,那么 A 的数组也是 B 的数组,并且完全可以在需要 B[] 的地方使用 A[]:

Integer[] intArray = new Integer[10];

Number[] numberArray = intArray;

上面的代码是有效的,因为一个 Integer 是 一个 Number,因而一个 In。

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

java 泛型集合应用_Java泛型集合的应用和方法相关推荐

  1. java 怎么为泛型参数赋值_Java泛型讲解

    1. 概述在引入泛型之前,Java类型分为原始类型.复杂类型,其中复杂类型分为数组和类.引入范型后,一个复杂类型 就可以在细分成更多的类型. 例如原先的类型List,现在在细分成List, List等 ...

  2. 描述java泛型引入原则_Java/泛型的类型擦除/README.md · oslo/LearningNotes - Gitee.com

    前言 Java 泛型(Generic)的引入加强了参数类型的安全性,减少了类型的转换,但有一点需要注意:Java 的泛型在编译器有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉,看下 ...

  3. java输出set集合元素_java Set集合,HashSet类详细介绍

    下面要给大家介绍的就是java Set集合方面的内容,本文主要讲到了HashSet类的一些知识,主要包括了HashSet类的特点,HashSet 类的常用构造方法重载形式以及代码演示了创建两种不同形式 ...

  4. java泛型常用特点_Java泛型详解

    对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在 ...

  5. java 接口的泛型方法_Java泛型/泛型方法/通配符/泛型接口/泛型泛型擦出

    从JDK1.5以后引入了三大常用新特性:泛型.枚举(enum).注解(Annotation).其中JDK1.5中泛型是一件非常重要的实现技术,它可以帮助我们解决程序的参数转换问题.本文为大家详细介绍一 ...

  6. java list 面试题_java【集合】面试题

    一.实例化数组后,能不能改变数组的长度? 不能,数组一旦实例化,他们的长度就是固定的. 二.List.Set.Map的区别? List中的元素:有序,可重复.可为空 set中的元素:无序.不可重复,只 ...

  7. java 集合枚举_java枚举集合怎么用

    在java枚举中可以结合集合进行操作,这里生成了一个新的类EnumSet.除此之外还有一个EnumMap集合需要我们掌握.下面我们就枚举集合的两种类进行说明,重点讲解EnumSet类的方法.代码及实例 ...

  8. java实现集合运算_java实现集合的运算

    package 期末算法设计; import java.util.HashMap; import java.util.HashSet; import java.util.Scanner; import ...

  9. java泛型与接口_Java泛型用于方法,类和接口

    什么是泛型? 型就是数据类型参数化.就是说原本定死的数据类型像方法中的形参一样,数据是不确定的,使用的时候由人传进去,泛型就是这样,数据类型不确定了.使用的时候再确定就可以了. 泛型的特点 是JDK1 ...

最新文章

  1. python画层次结构图_Maptree-层级结构数据展示的绝佳尝试
  2. 三维重建:SLAM算法的考题总结
  3. SAP CRM orgman set的更改会触发Pricing set的创建
  4. jsp做看板_如何使用看板做敏捷开发
  5. 【ELK】之Kibana使用
  6. dirname,basename的用法与用途
  7. easyui combobox下拉框 的取value text的API
  8. Ubuntu12.04上编译PlateGatewayQt
  9. matlab xls转csv,使用python或Matlab将csv文件中的数据转换为csv文件
  10. 模拟幅度调制系统抗干扰性能仿真分析[模板]
  11. 可汗学院公开课——统计学学习:62-81
  12. VirtualBox安装CentOS5.5 Insert Guest Additions CD image…(HOST+D)
  13. N多的红烧茄子做法!
  14. IOT漏洞挖掘学习笔记(一)——堆基础及相关数据结构
  15. winform遍历bartender_C# 调用Bartender服务并打印bartender标签
  16. C语言处理/proc/meminfo
  17. 大数据识别“爱”的羊毛党,拒绝那些它“恨”的羊毛党
  18. PCB设计黄金法则永不改变
  19. sparksql内写linux脚本,shell脚本调用spark-sql
  20. Flutter 中文文档:Flutter 应用里的国际化

热门文章

  1. DSTREAM-PT仿真器——ARM公司推出的最高性能的调试跟踪解决方案
  2. 关于display相关的一些内容(总体)
  3. linux下mysql无法看到3306端口监听
  4. video标签 添加视频
  5. jquery效果 窗口弹出案例
  6. mysql常用管理命令
  7. 怎么一步步编写简单的PHP的Framework(二十一)
  8. ubuntu共享无线链接
  9. Maven教程初级篇01: 简介
  10. 7系统启动到一半停止_太突然!国际饮料巨头计划狂砍一半品牌,这些饮料就快喝不到了…...