本文根据《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. jQuery遍历-祖先

    祖先是父.祖父或曾祖父等等. 通过 jQuery,您能够向上遍历 DOM 树,以查找元素的祖先. 向上遍历 DOM 树 这些 jQuery 方法很有用,它们用于向上遍历 DOM 树: parent() ...

  2. SpringMVC + Mybatis bug调试 SQL正确,查数据库却返回NULL

    今天碰到个bug,有点意思 背景是SpringMVC + Mybatis的一个项目,mapper文件里写了一条sql 大概相当于 select a from tableA where b = &quo ...

  3. Redis[三] @Hash 哈希

    Redis的哈希值是字符串字段和字符串值之间的映射,所以他们是表示对象的完美数据类型 在Redis中的哈希值,可存储超过400十亿键值对. redis 提供了2套操纵 一种是批量 一种是非批量 假设需 ...

  4. GreenOpenPaint简介

    一.项目概述 类似Windows系统下面的画图程序,但是已经从底层全部重新实现,改造成为"图像处理"类程序的基本运行框架. 由于是demo界面,较为简陋,但是因为框架已经搭建完善, ...

  5. ios 初体验<页面切换>

    本章类容:介绍如何新建一个页面,打开另一个页面 1.在前面中,在工程Appdelegate.m 里面程序第一个走的方法,新建一个窗口,视图,控制器,可视化等, 2.然后在ViewController. ...

  6. POJ 2449 Dijstra + A* K短路

    这题一开始的思路应该是直接从源点进行BFS搜索K短路. 但这样的复杂度在点数和K的值增大后将会变得很大. 而A*算法则构造一个h(x),在进行BFS时,每次都抛出最小的h(x)从而使汇点的出队速度加快 ...

  7. 从Object和Function说说JS的原型链

    ECMAScript规定了两个特殊的内置对象:Object和Function.他们的特殊性在于,他们本身既是对象又是函数,而他们同时也是对象和函数的构造器.这种自己生自己的逻辑显然违反人性,如果还停留 ...

  8. 团队作业9——Beta版本展示博客

    一. 骆杰宁(组长) 风格:少说话,多做事. 擅长技术:Jsp 编程兴趣:GUI 希望角色:PM 一句话宣言:年轻是本钱,不努力就不值钱. 胡丹丹 风格:不断沉淀自己 擅长技术:擅长TCP/IP协议模 ...

  9. Swing-JMenu菜单用法-入门

    菜单是Swing客户端程序不可获取的一个组件.窗体菜单大致由菜单栏.菜单和菜单项三部分组成,如下图所示: 由图可见,对于一个窗体,首先要添加一个JMenuBar,然后在其中添加JMenu,在JMenu ...

  10. Swing-setMaximumSize()用法-入门

    与setMinimumSize()一同讨论.顾名思义,这两个函数用于设置窗体的最大.最小值.然而测试发现,setMaximumSize()直接作用于JFrame时,无法实现其预定功能,setMinim ...