Java泛型简明解释

Java泛型由来的动机

理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你某些Java类型转换(casting)上的操作:

List<Apple> apples=...
Apple apple=apples.get(1);

如上的代码,就不用程序员手动做类型判断了,因为泛型,在编译阶段编译器就对类型进行了检查

泛型的构成

由泛型的构成引出了一个类型变量的概念。根据Java语言规范,类型变量是一种没有限制的标志符,产生于以下几种情况:

  • 泛型类声明
  • 泛型接口声明
  • 泛型方法声明
  • 泛型构造器(constructor)声明

泛型类和接口

public interface List<T> extends Collections<T>{

}

泛型方法和构造器(Constructor)

public static <T> getFirstItem(List<T> list){
}

泛型类型的子类型

假设有这么三种水果:

FujiApple,

Apple,

Fruit

FujiApple是Apple的子类,Apple是Fruit的子类,那么

List<FujiApple>,

List<Apple>,

List<Fruit>,

三者之间是什么关系呢?

List<Apple> apples=new ArrayList<Apple>();
List<Fruit> fruits=apples;

上面这段代码正确吗?答案是编译出错。

为什么呢?看下面这段代码

List<Apple> apples=new ArrayList<Apple>();
List<Fruit> fruits=apples;
fruits.add(new Strawberry());//Strawberry是草莓,是水果的子类型

如果Apple是Fruit的子类型,就认为List<Apple>是List<Fruit>的子类型,那么List<Fruit>自然就可以add草莓了。

但是这就违背了泛型是用来确定类型的这么一个公理。这样List<Fruit>中就用了多种类型了,那么拿出来的时候还是要手动

判断类型了。

所以List<Apple>跟List<Fruit>没有关系。

通配符

向上造型一个泛型对象的引用

List<Apple> apples=...
List<? extends Fruit> fruits=apples

如上代码,如果你想要两个泛型对象具有继承关系,可以使用通配符。

“? extends”是泛型类型的子类型相关性成为现实:Apple是Fruit的子类型,List<Apple> 是 List<? extends Fruit> 的子类型。

但是你从此不能往fruits里加入任何数据了,当然取出Fruit是可以的。

向下造型一个泛型对象的引用

List<Fruit> fruits=...
List<? super Apple> apples=fruits;

我们看到fruits指向的是一个装有Apple的某种超类(supertype)的List。同样的,我们不知道究竟是什么超类,但我们知道Apple和任何Apple的子类都跟它的类型兼容。既然这个未知的类型即是Apple,也是GreenApple的超类,我们就可以写入:

apples.add(new GreenApple);

apples.add(new Apple());

如果你试图往apples里加入任何apple的超类,编译器会警告你。

apples.add(new Fruit());

apples.add(new Object());

但是你需要取出对象的时候,取出的只能是Object对象。

存取原则和PECS法则

总结 ? extends 和 the ? super 通配符的特征,我们可以得出以下结论:

  • 如果你想从一个数据类型里获取数据,使用 ? extends 通配符
  • 如果你想把对象写入一个数据结构里,使用 ? super 通配符
  • 如果你既想存,又想取,那就别用通配符。

这PECS是指”Producer Extends, Consumer Super”

参考书籍:

时间: 2024-10-11 21:19:36

Java泛型简明解释的相关文章

Java泛型简明教程

Java泛型简明教程 博客分类: Java综合 JavaApple数据结构CC++ Java泛型简明教程 本文是从 Java Generics Quick Tutorial 这篇文章翻译而来. 泛型是Java SE 5.0中引入的一项特征,自从这项语言特征出现多年来,我相信,几乎所有的Java程序员不仅听说过,而且使用过它.关于Java泛型的教程,免费的,不免费的,有很多.我遇到的最好的教材有: The Java Tutorial Java Generics and Collections ,

java泛型具体解释

为什么引入泛型 bug是编程的一部分,我们仅仅能尽自己最大的能力降低出现bug的几率,可是谁也不能保证自己写出的程序不出现不论什么问题. 错误可分为两种:编译时错误与执行时错误.编译时错误在编译时能够发现并排除.而执行时错误具有非常大的不确定性,在程序执行时才干发现.造成的后果可能是灾难性的. 使用泛型能够使错误在编译时被探測到,从而添加程序的健壮性. 来看一个样例: public class Box{ private Object object; public void set(Object

Java 8简明教程

本文由 ImportNew - 黄小非 翻译自 winterbe. ImportNew注:有兴趣第一时间学习Java 8的Java开发者,欢迎围观<征集参与Java 8原创系列文章作者>. 以下是<Java 8简明教程>的正文. “Java并没有没落,人们很快就会发现这一点” 欢迎阅读我编写的Java 8介绍.本教程将带领你一步一步地认识这门语言的新特性.通过简单明了的代码示例,你将会学习到如何使用默认接口方法,Lambda表达式,方法引用和重复注解.看完这篇教程后,你还将对最新推

1月21日 - (转)Java 泛型

java泛型 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样. 可以在集合框架(Collection framework)中看到泛型的动机.例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象. 因为 M

java泛型的讲解

java泛型 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样. 可以在集合框架(Collection framework)中看到泛型的动机.例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象. 因为 M

java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

java泛型(二).泛型的内部原理:类型擦除以及类型擦除带来的问题 参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首要前提是理解类型擦出(type erasure). Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节码中是不包含泛型中的类型信息的.使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉.这个过程就称为类型

Java 泛型、通配符? 解惑

Java 泛型通配符?解惑 分类: JAVA 2014-05-05 15:53 2799人阅读 评论(4) 收藏 举报 泛型通配符上界下界无界 目录(?)[+] 转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T 有类型 ? 未知类型 一.通配符的上界 既然知道List<Cat>并不是List<Anilmal>的子类型,那就需要去寻找替他解决的办法, 是AnimalTrianer.act()方法变得更为通用(既可以接受List&

面向对象,Java泛型篇

一.Java泛型入门基础 1. 泛型历史:集合中可以存储任意类型对象,但是在取出时,如果要使用具体对象的特有方法时,需要进行向下转型,如果存储的对象类型不一致,在转型过程中就会出现ClassCastException异常.这样就给程序带来了不安全性. 在jdk1.5以后就有了解决方案--泛型技术:在存储元素时,就不允许存储不同类型的元素.存储了就编译失败. 所以就需要在存储元素时,在容器上明确具体的元素类型,这其实和数组定义很像. 2.优势:1)将运行时期的ClassCastException异

详解Java泛型type体系整理

一直对jdk的ref使用比较模糊,早上花了点时间简单的整理了下,也帮助自己理解一下泛型的一些处理. java中class,method,field的继承体系 java中所有对象的类型定义类Type 说明: Type : Type is the common superinterface for all types in the Java programming language. These include raw types, parameterized types, array types,