约束与局限性

不能用基本类型实例化类型参数

不能像Pair<double>这样调用,只能Pair<Double>,原因是类型擦除

运行时类型查询只使用于原始类型

虚拟机中的对象属于一个特定的非泛型类型,类型查询只能产生原始类型。

Pair<String> stringPair = ...;
Pair<Employee> employeePair = ...;
if (stringPair.getClass() == employeePair.getClass()) //相等的

不能创建参数化类型的数组

因为类型擦除会导致数组元素类型不安全

不能创建数组,但可以声明类型为Pair<String>[]的变量

向可变参数方法传递泛型类型实例,虚拟机会创建泛型类型数组,且会提示一个警告,使用@SupressWarnings("unchecked")或@SafeVarargs标注。

不能实例化类型变量
不能使用 new T(...)、new T[...]、T.class这样的类型变量

不能构造泛型数组
这里有数组中的一个知识点,数组类型之间不能强制类型转换,当Object[]引用赋给Comparable[]变量时,将会发生ClassCastException异常
擦除导致的
在静态方法中,构造静态方法有两种方式:
1.让用户提供数组构造器方法

public static <T extends Comparable> T[] minmax(IntFunction<T[]> constr, T... a) {
T[] mm = constr.apply(2);
...
}

2.使用反射

private static <T extends Comparable> T[] minmax2(T... args) {
T[] mm = (T[])Array.newInstance(args.getClass().getComponentType(), 2);
...
}

不能在静态域、静态方法中引用类型变量

会有编译时错误

不能抛出或捕获泛型类的对象,泛型类扩展Throwable是不合法的

可以消除对受查异常的检查

擦除后的冲突,比如以下泛型方法在擦除后会与Object的equals()产生冲突
public boolean equals(T value) {
return first.equals(value);
}
补救的办法是重新命名引发错误的方法。

泛型的继承规则

无论S与T有什么关系,Pair<S>与Pair<T>没有什么关系,以下代码有编译错误

Manager[] topHonchos = ...;
Pair<Employee> result = ArrayAlg.minmax(topHonchos); //error

在数组中,可以将一个Manager[]对象赋予一个Employee[]的变量,但虚拟机会监控数组元素的类型,如果试图将一个Employee对象存储到该数组中,会抛出ArrayStoreException异常

可以将参数化类型转化为原始类型,Pair<Employee>是原始类型Pair的子类。

泛型类可以扩展或实现其他泛型类,如ArrayList<Employee>类实现List<Employee>接口。

通配符类型

通配符类型,允许类型参数变化,定义如下。

Pair<? extends Employee>

此时的继承关系是,Pair<Employee> 或 Pair<Manager> > Pair<? extends Employee > Pair(原始类型)

超类型限定(supertype bound)

Pair<? super Manager>

超类型限定限制为Manager的所有超类型。

带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。

Java泛型相关总结(下)的更多相关文章

  1. Java泛型相关总结(上)

    最近在看<Java核心技术>泛型相关的部分,总结下. 泛型程序设计是什么? 泛型编程(generic programming)是计算机编程中的一种风格,类型通过参数指定.意味着编写的代码可 ...

  2. Java泛型type体系

    最近看开源代码,看到里面很多Java泛型,并且通过反射去获取泛型信息.如果说要看懂泛型代码,那还是比较容易,但是如果要自己利用泛型写成漂亮巧妙的框架,那必须对泛型有足够的了解.所以这两三天就不在不断地 ...

  3. 【Java心得总结四】Java泛型下——万恶的擦除

    一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...

  4. 什么情况下不能使用 Java 泛型

    1. 前言 Java 1.5 引入了泛型来保证类型安全,防止在运行时发生类型转换异常,让类型参数化,提高了代码的可读性和重用率.但是有些情况下泛型也是不允许使用的,今天就总结一下编码中不能使用泛型的一 ...

  5. Java:泛型基础

    泛型 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚很多! 解决这种限制的 ...

  6. Java深度历险(五)——Java泛型

      作者 成富 发布于 2011年3月3日 | 注意:QCon全球软件开发大会(北京)2016年4月21-23日,了解更多详情!17 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件 ...

  7. Java泛型-类型擦除

    一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变 ...

  8. java 深度探险 java 泛型

    Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在JD ...

  9. [转]Java 泛型: 什么是PECS(Producer Extends, Consumer Super)

    以下内容转自: 原文链接: stackoverflow 翻译: ImportNew.com- 刘志军 译文链接: http://www.importnew.com/8966.html -------- ...

随机推荐

  1. bootstrap中的.container类定义

    bootstrap中的.container类定义 .container{ padding-right:15px; padding-left:15px; margin-right:auto; margi ...

  2. springboot - websocket实现及原理

    本文章包括websocket面试相关问题以及spring boot如何整合webSocket. 参考文档 https://blog.csdn.net/prayallforyou/article/det ...

  3. socket.error: [Errno 99] Cannot assign requested address

    方法一:python 命令行下运行  vi /etc/hosts 将127.0.1.1 那一行的名字改成你的(用 vi /etc/hostname 获取) 127.0.0.1 localhost 12 ...

  4. Groovy学习笔记-实现接口

    1.单个委托方法的实现 button.addActionListener( { println 'Implement ActionListener' } as ActionListener ) 2.实 ...

  5. 国内第一本cbuilder开发web的宝典震撼登场(delphi也可参考)

    uniGUI入门到精通cBuilder版 众所周知,cbuilder和delphi是曾经风靡多年的强悍的万能的开发工具,岂奈大浪淘沙,B/S时代的到来让这对孪生兄弟隐姓埋名.然,无数风流人物依然对他们 ...

  6. MYSQL ini 配置文件详解及性能优化方案

    my.ini分为两块:Client Section和Server Section.   Client Section用来配置MySQL客户端参数.   要查看配置参数可以用下面的命令: show va ...

  7. 派生 de rive

    ''' de rive 派生 python2 (经典类|新式类) python3 (新式类) 1. What is derive? 什么是派生? 派生:子类定义自己新的属性,如果与父类同名,以子类自己 ...

  8. Matlab_spectrogram_短时傅里叶分析_实现与讨论

    在语音与音乐处理过程中,常用到短时傅里叶变换(Short Time Fourier Transformation, STFT).在一些学习路径中,STFT也是学习小波之前的预备知识.本文简单实现了 M ...

  9. JDK8.0接口中的默认方法和静态方法

    我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...

  10. shell 之扫描ip段

    #!/bin/sh domain=`echo $1|awk -F"." '{print $1"."$2"."$3"."} ...