1.  泛型类

public class Pair<T>
{
private T first;
private T second; public void setSecond(T second){...}
....
}

2.  泛型方法

class ArrAlg{
public static <T> T getMiddle(T... a){
return a[a.length/2];
}
}

3.   类型变量的限定

public static <T extends BoundingType1 & BoundingType2 ...> T min(T[] a)....

这表示T应该是BoundingType类型的子类型。T和绑定类型可以是类,也可以是接口 。一个类型变量或通配符可以有多个限定,但限定中之多只有一个类,这是因为单继承,当有多个限定时,基类要写在第一个,接口写在后面。

4.  原始类型,任何一个泛型类型,都自动提供一个原始类型,原始类型的名字就是删去类型参数后的类型名。例如Pair<T>, 原始类型就是Pair。

5.  泛型转换

  •   虚拟机中没有泛型,只有普通的类和方法
  • 所有的类型参数都用它们的第一个限定类型替换,没有写明限定类型就用Object
  • 合成桥方法保持多态。
  • 为保持类型安全性,必要时插入强制类型转换(例如调用泛型方法返回值)

5.  桥方法

假设有下列类继承了Pair<Date>,

class DateInterval extends Pair<Date>
{
public void setSecond(Date second){
.... }
}

实际擦除类型之后

class DateInterval extends Pair
{
public void setSecond(Date second){...} //因为类型擦除,实际还存在一个继承于Pair类的方法,显然这是两个方法
public void setSecond(Object second){
//实际生成桥方法,这里会调用setSecond(Date seconde);即:
setSecond((Date)second);
}
}

当如下调用时 Pair<Date> pair = new DateInterval(...);  pair.setSecond(aDate);。Pair类型只有一个方法setSecond(Object)。实际引用DateInterval类,因而将会调用DateInterval.setSecond(Object)。编译器为了调用最合适的方法,实际上生成了一个桥方法,如下 public void setSecond(Object second){  setSecond((Date) second)  } 。

6.  约束与局限性

  • 不能用基本类型实例化类型参数
  • 运行时类型查询只适用于原始类型
  • 不能创建参数化类型的数组,即不能 new Pair<String> [10]
  • 不能实例化类型变量,即不能使用 new T(...), new T[] 或T.class这类的表达式。可以通过反射实例化T但不能T.class.newInstance(); 可以如下设计API来实现。
public static <T> Pair<T> makePair(Class<T> cl){
try{
return new Pair<>(cl.newInstance(), cl.newInstance())
}catch(Exception e){return null;}
}
  • 泛型类的静态上下文中不能引用类型变量,例如 private static T aData; 或者 public static T fun(){}都是错误的。
  • 不能抛出或捕获泛型类的实例

7.  通配符

  • 通配符限定: extends 、super

例:Pair<? extends Person>表示泛型Pair类型,它的参数是Person的子类。

在这种情况下,getter和setter区别,getter可以正常调用,但是setter不行,会产生编译错误,因为编译器不能确定要传入参数的类型,也没法代替。

?extends Person getFirst()
void setFirst(? extends Person)

反之,通配符的超类型限定: ?super Student

void setFirst(? super Student);
? super Student getFirst();

编译器虽然不知道setFirst的确切类型,但是可以用任意Student对象调用,而不能用Person对象调用。如果调用getFirst,返回的对象不能保证,只能赋给Object。

  • 无限定通配符 Pair<?>
? getFirst();
void setFirst(?);

getFirst的返回值只能赋给一个Object, setFirst不能调用除非setFirst(null),对于一些简单操作非常有用,例如判定是否为null  getFirst() == null

  • 通配符捕获   可以通过泛型方法捕获通配符 

Java 泛型程序设计的更多相关文章

  1. java泛型(一)、泛型的基本介绍和使用

    现在开始深入学习java的泛型了,以前一直只是在集合中简单的使用泛型,根本就不明白泛型的原理和作用.泛型在java中,是一个十分重要的特性,所以要好好的研究下. 泛 型的定义:泛型是JDK 1.5的一 ...

  2. java泛型使用

    泛型的解释 现在感觉泛型是一个值得学习的地方,就抽出时间来学习和总结一下泛型的使用. Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允 ...

  3. Java泛型一:基本介绍和使用

    原文地址http://blog.csdn.net/lonelyroamer/article/details/7864531 现在开始深入学习java的泛型了,以前一直只是在集合中简单的使用泛型,根本就 ...

  4. java泛型 7 泛型的基本介绍和使用

    现在开始深入学习Java的泛型了,以前一直只是在集合中简单的使用泛型,根本就不明白泛型的原理和作用.泛型在java中,是一个十分重要的特性,所以要好好的研究下. 一.泛型的基本概念 泛型的定义:泛型是 ...

  5. Java基础语法<十二> 泛型程序设计

    1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element ( ...

  6. Java核心技术第八章——泛型程序设计(1)

    1.泛型程序设计 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用.例如:不希望为了聚集String和Integer对象分别设计不同的类.(个人觉得此处说的聚集译为:创建一个对象,属性可以为 ...

  7. Java核心技术卷一基础知识-第12章-泛型程序设计-读书笔记

    第12章 泛型程序设计 本章内容: * 为什么要使用泛型程序设计 * 定义简单泛型类 * 泛型方法 * 类型变量的限定 * 泛型代码和虚拟机 * 约束与局限性 * 泛型类型的继承规则 * 通配符类型 ...

  8. Java核心技术-泛型程序设计

    使用泛型机制编写的代码要比那些杂乱地使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性. 泛型对于集合类尤其有用 1 为什么要使用泛型程序设计 泛型程序设计意味着编写的代码可以 ...

  9. 《Java核心技术(卷1)》笔记:第8章 泛型程序设计

    (P 327)"菱形"语法: ArrayList<String> files = new ArrayList<>(); // Java 9 扩展了菱形语法的 ...

随机推荐

  1. 如何用空气质量查询API接口进行快速开发

      空气质量的好坏反映了空气污染程度,它是依据空气中污染物浓度的高低来判断的.空气污染是一个复杂的现象,在特定时间和地点空气污染物浓度受到许多因素影响.来自固定和流动污染物的人为污染物排放大小是影响空 ...

  2. 2022.7.19 $\mathcal{S\,\,T\,L}$

    \(STL\) 容器的共有特征:.begin() .end()//表示最后一个元素的后面那个位置 .size()//无符号整型 .swap(b) ::iterator//迭代器 关于迭代器 迭代器可以 ...

  3. 【USACO 2012 Open】奶牛赛跑_题解

    奶牛赛跑 目录 奶牛赛跑 题目描述 输入格式 输出格式 样例 样例输入#1 样例输出#1 题解 代码 题目描述 约翰有头奶牛,他为这些奶牛准备了一个周长为的环形跑牛场.所有奶牛从起点同时起跑,奶牛在比 ...

  4. typescript中的--strictFunctionTypes选项

    什么是协变和逆变 原来,在泛型参数上添加了in关键字作为泛型修饰符的话,那么那个泛型参数就只能用作方法的输入参数,或者只写属性的参数,不能作为方法返回值等,总之就是只能是"入",不 ...

  5. Calendar类介绍_获取对象的方式和Calendar类的常用成员方式

    java.util.Calendar是日历类,在Date后出现,替换掉了许多Date方法.该类将所有可能用到的时间信息封装为静态成员变量,方便获取.日历类就是方便获取各个时间属性的. Calendar ...

  6. 重写并自定义依赖的原生的Bean方法

    转载请注明出处: 在项目开发过程中,往往是直接应用很多jar包中依赖且声明好的Bean,拿来即用,但很多场景也需要对这些原生的Bean 进行自定义,定制化封装,这样在项目使用的过程中,可以使用自定义的 ...

  7. 【springcloud】环境搭建与Rest使快速上手

    SpringCloud环境搭建 --- Rest使用 个人主页:https://www.cnblogs.com/xbudian/ 今天来到SpringCloud的学习,我们从spring boot微服 ...

  8. JavaScript 异步编程(一):认识异步编程

    前言 "异步"的大规模流行是在 Web 2.0浪潮中,它伴随着 AJAX 席卷了 Web.前端充斥了各种 AJAX 和事件,这些都是典型的异步应用场景.现在的 Web 应用已经不再 ...

  9. 在 Linux 安装 Java 的流程

    前言 安装流程一共为 4 个步骤,分为下载.解压.配置.检查. 下载 Oracle 官网下载 JDK. 解压 上传至 Linux 中(可使用宝塔面板上传),解压安装包: ubuntu@VM-0-6-u ...

  10. 字符串KMP——用途广泛的字符串匹配算法 + 扩展KMP——特殊定义的字符串匹配

    引 入 引入 引入 " SY 和 WYX 在看毛片.(几 毛 钱买到的动作 片,毛 片) WYX 突然想回味一个片段,但是只记得台词里面有一句挺长的 " ∗ ∗ ∗ ∗ **** ...