本文根据《Java核心卷轴》第十二章总结而来,更加详细的内容请查看《Java核心卷轴》

1. 泛型类型只能是引用类型,不可以使用基本数据类型。

2. 类型变量含义

   E : 集合    K : 关键字    V : 值      T : 任意类型

3. 泛型类

  3.1  注意事项

    类型变量声明放在类名的后面

  3.2 示例

package com.BlueStarWei.generic;

public class Pair<T> {

    private T first;
private T second; public Pair(T first, T second) {
this.first = first;
this.second = second;
} public T getFirst() {
return first;
}
public void setFirst(T first) {
this.first = first;
}
public T getSecond() {
return second;
}
public void setSecond(T second) {
this.second = second;
}
}

4. 泛型方法

  4.1 注意事项

    类型变量放在修饰符的后面,返回类型的前面

  4.2 示例

package com.BlueStarWei.generic;

public class GenericMethodDemo{
public static void main(String[] args) {
String s = getMiddle("Hello","world","Happy");
System.out.println(s);//World
} //T... 表示可以输入任意个数的参数
public static <T> T getMiddle(T... a){
return a[a.length / 2];
}
}

5. 类型变量的限定<T extends BoundingType>

  5.1 T应该是绑定类型的子类型。T和绑定类型可以是类,也可以是接口。

  5.2 一个类型变量可以有多个限定;如: T extends Comparable &  Serializable

  5.3 示例

package com.BlueStarWei.generic;

public class BoundingTypeDemo {
public static void main(String[] args) {
Integer[] a = new Integer[]{1,2,3,4};
int max = getMax(a);
System.out.println(max); } public static <T extends Comparable<T>> T getMax(T[] a){
if(a == null || a.length == 0) return null;
T max = a[0];
for (int i = 0; i < a.length; i++) {
if(max.compareTo(a[i]) < 0){
max = a[i];
}
}
return max;
} }

6. 运行时类型检查只适用于原始类型

  6.1 校验情况

if(a instanceof Pair<String>) //编译报错
if(a instanceof Pair<T>) //编译报错
if(a instanceof Pair) //true

  6.2 getClass返回的是原始类型

Pair<String> a = new Pair<String>("Hello", "World");
Pair<Integer> b = new Pair<Integer>(1,2);
if(a.getClass().equals(b.getClass())){
System.out.println("true");
//class com.ebao.gs.pol.nb.test.Pair
System.out.println(a.getClass());
}else{
System.out.println("false");
}

7. Java不支持泛型类型的数组

  7.1 示例

Pair<String>[] as = new Pair<String>[10]; //编译报错

  7.2 解决方案: 将参数化对象放入ArrayList

List<Pair<String>> list = new ArrayList<Pair<String>>();

8. 通配符的限定

  8.1 子类型限定

    8.1.1 Pair<? Extends Employee>不能调用setFirst方法,但是可以调用getFirst方法

? extends Employee  getFirst()
void setFirst(? extends Employee)

   调用setFirst方法时,编译器只知道需要某个Employee的子类型,但是不知道具体什么类型。它拒绝传递任何特定类型(?不能用来匹配)。调用getFirst方法时,只是将getFirst的返回值赋值给一个Employee的引用,完全合法。

    8.1.2 示例

public static void minMaxBonus(Manager[] manager, Pair<?
extends Manager> result) {
if(manager.length == 0 || manager == null) return;
Manager minManager = manager[0];
Manager maxManager = manager[0];
for (int i = 0; i < manager.length; i++) {
if(manager[i].getBonus() < minManager.getBonus())
minManager = manager[i];
if(manager[i].getBonus() > maxManager.getBonus())
maxManager = manager[i];
}
result.setFirst(minManager);//编译报错
result.setSecond(maxManager);//编译报错
Manager m = (Manager)result.getFirst();
System.out.println(m.getBonus());

  8.2 超类型限定

    8.2.1 Pair<? super Manager>可以调用setFirst方法,但是调用getFirst方法会返回Object对象(可以类型强转)

void setFirst(? super Manager)
? super Manager getFirst()

  编译器不知道setFirst方法的确切类型,但是可以用任意Manager对象(或子类型)调用它。然而,如果调用getFirst方法,返回的对象类型就得不到保证。只能把它赋值给一个Object(但是可以类型强制转换)。

    8.2.2 示例

public static void minMaxBonus(Manager[] manager, Pair<?
super Manager> result) {
  if(manager.length == 0 || manager == null) return;
  Manager minManager = manager[0];
  Manager maxManager = manager[0];
  for (int i = 0; i < manager.length; i++) {
  if(manager[i].getBonus() < minManager.getBonus())
  minManager = manager[i];
  if(manager[i].getBonus() > maxManager.getBonus())
  maxManager = manager[i];
    }
  result.setFirst(minManager);
  result.setSecond(maxManager);
  Manager m = (Manager)result.getFirst();
  System.out.println(m.getBonus()); }

  8.3 总结

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

  8.4 附表(Manager类)

package com.ebao.gs.pol.nb.test;

public class Manager {
private Long id;
private String name;
private Double bonus; public Manager(Long id, String name, Double bonus){
super();
this.id = id;
this.name = name;
this.bonus = bonus;
} public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getBonus() {
return bonus;
}
public void setBonus(Double bonus) {
this.bonus = bonus;
} }

9.泛型的意义

  减少强制类型转换的使用

更多内容,请关注:http://www.cnblogs.com/BlueStarWei/

java核心卷轴之泛型程序设计的更多相关文章

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

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

  2. java核心卷轴之集合

    1. Iterator 1.1 注意事项 接口的remove方法将删除上次调用next方式时返回的对象,即:remove之前,必须有next(先获取,再删除). 1.2 例一:删除字符串集合中的第一个 ...

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

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

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

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

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

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

  6. Java Collections API和泛型

    Java Collections API和泛型 数据结构和算法 学会一门编程语言,你可以写出一些可以工作的代码用计算机来解决一些问题,然而想要优雅而高效的解决问题,就要学习数据结构和算法了.当然对数据 ...

  7. 小白学Java:老师!泛型我懂了!

    目录 小白学Java:老师!泛型我懂了! 泛型概述 定义泛型 泛型类的定义 泛型方法的定义 类型变量的限定 原生类型与向后兼容 通配泛型 非受限通配 受限通配 下限通配 泛型的擦除和限制 类型擦除 类 ...

  8. 深入Java核心 Java中多态的实现机制(1)

    在疯狂java中,多态是这样解释的: 多态:相同类型的变量,调用同一个方法时,呈现出多中不同的行为特征, 这就是多态. 加上下面的解释:(多态四小类:强制的,重载的,参数的和包含的) 同时, 还用人这 ...

  9. Java核心 --- 枚举

    Java核心 --- 枚举 枚举把显示的变量与逻辑的数字绑定在一起在编译的时候,就会发现数据不合法也起到了使程序更加易读,规范代码的作用 一.用普通类的方式实现枚举 新建一个终态类Season,把构造 ...

随机推荐

  1. lnmp架构(第一篇)

    lnmp 架构 第一篇 nginx 源码安装 nginx的安装包:nginx-1.12.0.tar.gz 建议安装前的修改: 在nginx的解压包中修改文件nginx-1.12.0/src/core/ ...

  2. [2014-08-18]Mac OSX 命令行快捷键

    系统:OSX 10.9.4 将光标移动到行首:ctrl + a 将光标移动到行尾:ctrl + e 清除屏幕: ctrl + l 搜索以前使用命令:ctrl + r 清除当前行: ctrl + u 清 ...

  3. JRE 和 JDK 的区别

    JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的.   JDK顾名思义是java开发 ...

  4. Ext:ComboBox实战

    var gsCombo = new Ext.form.ComboBox({ id:'combo', hiddenName:'value', fieldLabel:'下拉框', triggerActio ...

  5. Keil报错failed to execute 'd:\Keil\C51\BIN\C51.EXE'

    关于老师发的keil软件报错如下: --- Error: failed to execute 'd:\Keil\C51\BIN\C51.EXE' 错误是因为老师直接拷贝的安装目录,里面的文件路径设置仍 ...

  6. JS中的函数和BOM

    文档注释:开头两个*.写在函数上方,在调用函数时, 可以看到文档中的描述信息:function aaa(){ } [函数的声明及调用] 1.函数的声明格式: function 函数名(参数1,参数2, ...

  7. 安装mariadb二进制程序

    author:JevonWei 版权声明:原创作品 下载mariadb软件包 https://downloads.mariadb.org/mariadb/5.5.57/ 一.创建用户和准备数据目录 1 ...

  8. spring配置datasource三种方式

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp34 spring配置datasource三种方式 1.使用org.spri ...

  9. JS常用方法总结

    1.javascript删除元素节点 IE中有这样一个方法:removeNode(),这个方法在IE下是好使的,但是在Firefox等标准浏览器中就会报错了 removeNode is not def ...

  10. Liunx-常用命令的总结(5)

    cd     ../dir        上一节目录下dir目录 cd -                    返回上次目录 ifconfig            查看IP地址 sudo   if ...