0 Java核心技术-目录

2020/01/15 posted in  Java核心技术

01Java程序设计概述

Java程序设计平台

Java“白皮书”的关键术语

Java applet与Internet

Java发展简史

关于Java的常见误解

2019/03/28 posted in  Java核心技术

02Java程序设计环境

2019/03/28 posted in  Java核心技术

03Java的基本程序设计结构

2019/03/28 posted in  Java核心技术

04对象与类

2019/03/28 posted in  Java核心技术

05继承

2019/03/28 posted in  Java核心技术

06接口、lambda表达式与内部类

2019/03/28 posted in  Java核心技术

07异常、断言和日志

2019/03/28 posted in  Java核心技术

08 泛型程序设计

使用泛型机制编写的程序代码要比哪些杂乱地使用Object变量,然后在进行强制类型转换的代码具有更好的安全性和可读性。泛型对于集合类尤其有用,例如,ArrayList就是一个无处不在的集合类。

1 为什么要使用泛型程序设计

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。

1.1 类型参数的好处

不使用泛型的问题:

  1. 当获取一个值时必须进行强制类型转换。
  2. 操作时没有错误检查。

泛型提供的解决方案类型参数(type parameters),使得程序具有更好的可读性和安全性。

如ArrayList,声明时即可知道数据类型,并且添加数据时有检查,可以避免插入错误类型的数据。

1.2 谁想成为泛型程序员

泛型程序员的任务就是预测出所用类的未来可能有的所有用途。
通配符类型(wildcard type),可以帮助库的构建者编写出尽可能灵活的方法。

2 定义简单泛型类

一个泛型类(generic class)就是一个或多个类型变量的类。

public class Pair<T> {
    
    private T first;
    private T second;

    public Pair() { first = null;second = null; }

    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; }
}

Pair类引入了一个类型变量T,用<>括起来,并放在类型后面。泛型类可以有多个类型变量。
类定义中的 类型变量 指定 方法的返回类型 以及 域和局部变量的类型。

3 泛型方法

定义一个带有类型参数的简单方法:

class ArrayAlg {

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

4 类型变量的限定

有时,类或者方法需要对类型变量加以约束。解决方案是将T限制为实现某个接口。

public static <T extends Comparable> T min(T[] a)...

一个类型变量或通配符可以有多个限定:

T extends Comparable & Serializable

5 泛型代码和虚拟机

虚拟机没有泛型类型对象--所有对象都属于普通类。

5.1 类型擦除

无论何时定义一个泛型类型,都自动提供了一个相应的原始类型(raw type)。原始类型的名字就是删去类型参数后的泛型类型名。擦除(erased)类型变量,并替换为限定类型(无限定的变量用Object)。

5.2 翻译泛型表达式

当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换。

5.3 翻译泛型方法

类型擦除也会出现在泛型方法中。

类型擦除与多态发生冲突。解决这个问题,编译器会生成一个桥方法(bridge method)。

Java泛型转换的事实:

  • 虚拟机中没有泛型,只有普通的类和方法。
  • 所有的类型参数都用它们的限定类型替换。
  • 桥方法被合成来保存多态。
  • 为保持类型安全性,必要时插入强制类型转换。

5.4 调用遗留代码

设计Java泛型类型时,主要目标是运行泛型代码和遗留代码之间能够互操作。

6 约束与局限性

Java泛型使用时要考虑一些限制,大多数限制都是由类型擦除引起的。
(todo暂时只有介绍,没有原因说明)

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

没有Pair<double>,只有Pair<Double>。

原因是类型擦除之后,Pair类含有Object类型的域,而Object不能存储double值。

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

虚拟机中的对象总有一个特定的非泛型类型。因此,所有的类型查询只产生原始类型。

if (a instanceof Pair<String>) //error
Pair<String> p = (Pair<String>) a;//Warning

Pair<T>的gatClass将返回Pair.class

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

Pair<String>[] table = new Pair<String>[10];//error

如果需要收集参数化类型对象,使用ArrayList<Pair<String>>。

6.4 Varargs警告

@SuppressWarnings("unchecked")和@SafeVarargs抑制警告。

6.5 不能实例化类型变量

不能使用像new T(...),new T[...]或T.class这样的表达式中的类型变量。

6.6 不能构造泛型数组

public static <T extends Comparable> T[] minmax(T[] a) { T[] mm = new T[2]; ...}//error

6.7 泛型类的静态上下文中类型变量无效

public class Singleton<T>{
    private static T instance;  //error
    public static T getInstance(){...}  //error
}

6.8 不能抛出或捕获泛型类的实例

public class Problem<T> extends Exception {/**...**/}//error

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

6.10 注意擦除后的冲突

public boolean equals(T value){...}//error

方法擦除equals(T)就是equals(Object),与Object.equals方法冲突。

7 泛型类型的继承规则

无论S与T有什么关系,通常Pair<S>与Pair<T>没有什么联系。

8 通配符类型

8.1 通配符的概念

通配符类型中,运行类型参数变化。如Pair<? extends Employee>,表示任何泛型Pair类型。

8.2 通配符的超类型限定

通配符还可以指定一个超类型限定,? super Manager
带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。

public static <T extends Comparable<? super T>> T min(T[] a)

有可能被声明为使用类型T的对象,也有可能使用T的超类型。

8.3 无限定通配符

还可以使用无限定的通配符,如Pair<?>。

Pair<?>和Pair本质的不同在于:可以用任意Object对象调用原始Pair类的方法。它对于许多简单操作非常有用,比如hasNulls(Pair<?> p)。

8.4 通配符捕获

9 反射和泛型

9.1 泛型Class类

9.2 使用Class参数进行类型匹配

9.3 虚拟机中的泛型类型信息

2019/03/28 posted in  Java核心技术

09集合

2019/03/28 posted in  Java核心技术

10图形设计程序

2019/03/28 posted in  Java核心技术

11事件处理

2019/03/28 posted in  Java核心技术

12Swing用户界面组件

2019/03/28 posted in  Java核心技术

13部署Java应用程序

2019/03/28 posted in  Java核心技术

14 并发

14.1 什么是线程

14.1.1 使用线程给其他任务提供机会

14.2 中断线程

14.3 线程状态

14.3.1 新创建线程

14.3.2 可运行线程

14.3.3 被阻塞线程和等待线程

14.3.4 被终止的线程

14.4 线程属性

14.4.1 线程优先级

14.4.2 守护线程

14.4.3 未捕获异常处理器

14.5 同步

14.5.1 竞争条件的一个例子

14.5.2 竞争条件详解

14.5.3 锁对象

14.5.4 条件对象

14.5.5 synchronized关键字

14.5.6 同步阻塞

14.5.7 监视器概念

14.5.8 Volatile域

14.5.9 final变量

14.5.10 原子性

14.5.11 死锁

14.5.12 线程局部变量

14.5.13 锁测试与超时

14.5.14 读/写锁

14.5.15 为什么弃用stop和suspend方法

14.6 阻塞队列

14.7 线程安全的集合

14.7.1 高效的映射、集和队列

14.7.2 映射条目的原子更新

14.7.3 对并发散列映射的批操作

14.7.4 并发集视图

14.7.5 写数组的拷贝

14.7.6 并行数组算法

14.7.7 较早的线程安全集合

14.8 Callable与Future

14.9 执行器

14.9.1 线程池

14.9.2 预定执行

14.9.3 控制任务组

14.9.4 Fork-Join框架

14.9.5 可完成Future

14.10 同步器

14.10.1 信号量

14.10.2 倒计时门栓

14.10.3 障栅

14.10.4 交换器

14.10.5 同步队列

14.11 线程与Swing

14.11.1 运行耗时的任务

14.11.2 使用Swing工作线程

14.11.3 单一线程规则

2019/03/28 posted in  Java核心技术