本文根据《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. koa/redux middleware系统解析

    middleware 对于现有的一些框架比如koa,express,redux,都需要对数据流进行一些处理,比如koa,express的请求数据处理,包括json.stringify,logger,或 ...

  2. web安全:QQ号快速登录漏洞及被盗原理

    为什么你什么都没干,但QQ空间中却发了很多小广告?也许你的QQ账号已经被盗.本文将讲解一个QQ的快速登录的漏洞. 我前阵子在论坛上看到一个QQ的快速登录的漏洞,觉得非常不错,所以把部分原文给转到园子来 ...

  3. C++中static关键字作用总结

    1.先来介绍它的第一条也是最重要的一条:隐藏.(static函数,static变量均可) 当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.举例来说明.同时编译两个源文件 ...

  4. CSS 中的 initial、inherit、unset、revert

    在css中,initial(初始).inherit(继承).unset(未设置).revert(还原)这四个关键字可以应用于所有的CSS属性. initial - 初始默认值.IE不支持 inheri ...

  5. C# 导出Excel的示例(转)

    using System; using System.Collections.Generic; using System.Text; using System.Data; using System.W ...

  6. 第3阶段——内核启动分析之start_kernel初始化函数(5)

    内核启动分析之start_kernel初始化函数(init/main.c) stext函数启动内核后,就开始进入start_kernel初始化各个函数, 下面只是浅尝辄止的描述一下函数的功能,很多函数 ...

  7. Java线程:线程栈模型

    要理解线程调度的原理,以及线程执行过程,必须理解线程栈模型. 线程栈是指某时刻时内存中线程调度的栈信息,当前调用的方法总是位于栈顶.线程栈的内容是随着程序的运行动态变化的,因此研究线程栈必须选择一个运 ...

  8. MPLS LDP随堂笔记1

    LDP 的使用原因(对于不同协议来说) LDP的四大功能 发现邻居 hello 5s 15s 224.0.0.2 发现邻居关系 R1 UDP 646端口 R2 UDP 646端口 此时形成邻居 建立邻 ...

  9. 团队作业8——第二次项目冲刺(Beta版本)5.24

    1.当天站立式会议照片 会议内容 1.总结前几次会议中出现的问题. 2.对第二天需要做的任务进行分配. 3.询问团队队员任务完成情况以及时间分配是否充分. 4.对今后的任务,发表自己的看法. 2.每个 ...

  10. JAVA基础第六组(5道题)

    26.[程序26] 题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母.         1.程序分析:用情况语句比较好,如果第一个字母一样,则判断用情况语句 ...