《Java核心技术》 Reading Notes

啊,先感叹一句找实习不易。为了准备Java开发岗位的面试,也为了重新过一遍Java的基础知识,就买了这本知乎上口碑还不错的《Java核心技术》(原版名为《Core Java》)来看。作者叫Cay S. Horstmann,他是San Jose State University(传说中的SJSU)的计算机科学系教授,Java的倡导者之一。读下来总体感觉内容比较全面,确实比较适合初学者。对我来讲,集合、并发这两章补了不少知识漏洞。唯一不足的就是翻译有点不清楚,特别是反射,泛型这些地方。这里摘录一些容易忘记的知识点。

基础

James Gosling
applet: 在网页中运行的Java程序
程序语言的成功更多取决于支撑系统的能力,而不是优美的语法
JRE包含JVM
Abstract Window Toolkit(AWT) 事件处理; Swing用户界面
UML(Unified Modeling Language)
集合接口与实现分离
注释不能嵌套,/*会去匹配下面最近的*/
8种基本类型(4个整型,2个浮点型,char,boolean),所占字节数固定与平台无关
boolean与整型不能转换
数字初始化为0,boolean初始化为false,引用初始化为null
0b: 二进制
>>>: 逻辑右移
一个字符 -> 一个代码点 -> 一个或两个代码单元
首先检查是否为null
enum E = {A, B, C};

1
2
3
4
label:
{
break; //跳转到label语句块后
}

Java二维数组第一维存的是地址,每个地址再另外分配第二维空间
C二维数组是一个连续的内存块
final: 不可变,构造时必须初始化
static: 类特有的且不属于任何对象
strictfp: 严格的浮点运算
private: 只能由该类访问
protected: 只能由该类,其子类以及同一个包内访问
public: 任何类都能访问
默认为包内可访问
javadoc: 源文件生成HTML文档
String… args: 可变数量参数,本质上是数组
JAR: Java Archive,使用ZIP格式压缩
读写用户配置信息使用Properties和Preferences类

对象与类

面向过程: 全局数据 + 多个过程
面向对象: 多个对象数据 + 多个方法
对象三要素: 行为,状态,标识
封装(Encapsulation): 仅通过对象方法与对象数据交互
访问器方法(accessor method),更改器方法(mutator method)
this: 隐式参数表示调用本方法的对象,也可以表示其他构造器
方法参数本质上传值,只是对于引用类型的值是引用
方法签名(signature): 方法名 + 参数
重载(overload): 方法名相同,参数类型、数量不同
若已经提供有参构造器,则系统不会提供无参构造器,需要自行提供
初始化块先于构造器执行,static块在类第一次加载时执行
import static java.lang.Math.*; //静态导入

继承(extends)

子类(subclass)在超类(superclass)的基础上扩展新的域和方法
super: 调用超类方法或构造器
子类构造器会默认调用超类无参构造器,除非显式调用super
多态(polymorphism): 一个对象变量可以指向多种类型
动态绑定(dynamic binding): 运行时自动选择调用超类或子类的方法
调用方法步骤: 查找类的方法表,重载解析,查看静态绑定,查看动态绑定
final: 类不能被继承,方法不能被覆盖
object instanceof class: 测试一个对象是否为一个类的实例,在超类转子类前做检查
abstract: 包含抽象方法的类为抽象类,可以有具体域和方法,不能实例化,子类可为抽象类也可实现全部抽象方法
int -> Integer: 包装器类
list.add(3) -> list.add(Integer.valueOf(3)): 自动装箱
Object.equals(a, b); //null安全
反射(Reflection): 运行时动态获取类的信息及调用对象方法
object.getClass(); Class.forName(s); Class.class;
Field, Method, Constructor

接口(implements)

interface: 类的需求描述,只有方法签名或常量,不加访问修饰符,可以被继承
default: 默认方法
浅拷贝: 部分域对象没有拷贝; 深拷贝: 所有域都拷贝
lambda表达式: 函数式编程
(type param) -> {method} <=> class::method(方法引用)
函数式接口: lambda表达式可以代替只有一个抽象方法的接口
内部类: 访问外围类的域,对外隐藏

异常、断言和日志

Throwable <- Error, Exception
Exception <- IOException, RuntimeException
受查异常: IOException,必须提供异常处理器或抛出异常
非受查异常: Error, RuntimeException

1
2
3
public void function throws IOException {
throw new IOException(“exception!”);
}

断言: 检测前置条件是否成立,能够灵活被启用或禁用,用于开发测试阶段
assert condition:expression;
日志: 能够灵活被启用或禁用,具有不同级别
Logger.getLogger();

泛型编程(Generic Programming)

泛型类: public class c<T>
泛型方法: public <T> T function(T param)
类型限定: <T extends class/interface>
通配符: <? extends/super class/interface>
虚拟机会进行类型擦除,将泛型替换为原始类型
不能构造泛型数组
若泛型T和U有继承关系,则class<T>class<U>没有继承关系

并发

Thread类本身实现了Runnable接口
推荐实现Runnable接口,能够继承别的类,每次创建线程可以使用同一个HelloRunnable类

1
2
3
4
5
6
7
8
9
10
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
Runnable hr = new HelloRunnable();
Thread t = new Thread(hr);
t.start();
}
}

不推荐继承Thread类,无法继承别的类,每次创建线程需要new一个HelloThread类

1
2
3
4
5
6
7
8
public class HelloThread extends Thread {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}

Thread.currentThread();
State: New, Runnable, Blocked, Waiting, Timed waiting, Terminated
t.join(); //current thread pauses execution until t terminates
Lock(锁对象): 每一个对象都有一个内部锁,对critical section加锁
ReentrantLock, ReentrantReadWriteLock
Condition(条件对象): 不满足条件则放弃锁await,等待signalAll
synchronized: 使用对象的内部锁和条件
volatile: 告知编译器和虚拟机该变量会被并发更新
监视器: 每个方法强制加锁
阻塞队列BlockingQueue: 生产者线程插入元素,消费者线程取出元素,底层实现线程安全
Callable: 异步调用
Future: 保存异步调用的结果
Executors(执行器): 创建线程池