文章目录
- Java核心技术卷一读书笔记
- 第一章 Java程序设计概述
- 1.1 关键特性
- 第二章 Java程序设计环境
- 2.1 使用命令行工具
- 第三章 Java的基本查询设计结构
- 3.1 数据类型
- 3.2 运算符
- 3.3 数值之间的合法转换
- 3.4 输入输出
- 3.5 控制流程
- 第四章 对象与类
- 4.1 用户自定义类
- 4.2 方法参数
- 4.3 对象构造
- 4.4 类设计技巧
- 第五章 继承
- 5.1 类、超类和子类
- 5.2 Object:所有类的超类
- 5.3 泛型数组列表
- 5.4 对象包装器与自动装箱
- 5.5 参数数量可变的方法
- 5.6 反射
- 5.7 继承的设计技巧
- 第六章 接口、Lambda表达式与内部类
- 6.1 接口
- 6.2 Lambda表达式
- 6.3 内部类
- 6.4 代理
- 第七章 异常、断言和日志
- 7.1 处理错误
- 7.2 捕获异常
- 7.3 使用异常机制的技巧
- 7.4 记录日志
- 第八章 泛型程序设计
- 8.1 好处
- 8.2 定义简单泛型类
- 8.3 泛型方法
- 8.4 类型变量的限定
- 8.5 泛型代码和虚拟机
- 8.6 约束与局限性
- 8.7 通配符类型
- 8.8 反射和泛型
- 第九章 集合
- 9.1 Java集合框架
- 9.2 具体集合
- 9.3 映射
- 第十章 并发
- 10.1 线程
- 10.2 线程中断
- 10.3 线程状态
- 10.4 线程属性
- 10.5 同步
Java核心技术卷一读书笔记
第一章 Java程序设计概述
1.1 关键特性
- 简单
- 面向对象
- 分布式
- 健壮性
- 安全性
- 体系结构中立
- 可移植性
- 解释性
- 高性能性
- 多线程
- 动态性
第二章 Java程序设计环境
2.1 使用命令行工具
- 注意:
- 注意大小写
- 编译器需要一个文件名,而运行程序时,只需要指定类名,不需要扩展名
第三章 Java的基本查询设计结构
3.1 数据类型
- 八种基本类型:四种整型、两种浮点类型、char和boolean。
- 整型:
- int
- short
- long
- byte
- 浮点类型
- float 后缀f
- double 后缀d或者没有
- 布尔值boolean:整型和布尔值之间不能进行转化
3.2 运算符
- 使用strictfp可以保证严格的浮点计算。
3.3 数值之间的合法转换
3.4 输入输出
- 读取输入
- 需要构造一个Scanner对象,并与标准输入流System.in关联。
- 密码的输入
- 使用Console类
一个JVM是否有可用的Console,依赖于底层平台和JVM如何被调用。如果JVM是在交互式命令行(比如Windows的cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的Console实例。
但当使用Eclipse等IDE运行以上代码时Console中将会为null。
表示Java程序无法获得Console实例,是因为JVM不是在命令行中被调用的,或者输入输出被重定向了。
- 格式化输出
- 可以使用s转换符格式化任意的对象。对于任意实现了Formattable接口的对象都将调用formatTo方法。否则将调用toString方法。
3.5 控制流程
- switch
- case标签:
- 类型为char、byte、short、或int的常量表达式
- 枚举常量
- 字符串字面量
第四章 对象与类
4.1 用户自定义类
- 构造器
- 构造器与类同名
- 每个类有一个以上的构造器
- 构造器可以有多个或者没有参数
- 构造器没有返回值
- 构造器总是伴随着new操作一起调用的
- 隐式参数与显式参数
- 隐式:是出现在方法名前面的类对象
- 显式:位于方法名后括号中
在每一个方法中关键字this表示隐式参数
4.2 方法参数
- 参数传递
- 按值调用:表示方法接收的是调用者提供的值(java)
- 按引用调用:表示方法接收的是调用者提供的变量地址
- java对对象采用的不是引用代用,是按值传递
- 一个方法不能修改一个基本数据类型的参数(数值型或布尔型)
- 一个方法可以改变一个对象参数的状态
- 一个方法不能让对象参数应用一个新的对象
4.3 对象构造
- 调用另一个构造器
- 使用this
4.4 类设计技巧
- 一定要保证数据私有
- 一定要对数据初始化
- 不要再类中使用过多的基本类型
- 不是所有的域都需要独立的与访问器和域更改器
第五章 继承
5.1 类、超类和子类
- 关键词super使用父类的方法。
- 如果子类的构造器没有显式地调用超类的构造器,则将自动地调用超类默认的构造器。
this:
引用隐式参数
调用该类其他的构造器
super
调用超类的方法
调用超类的构造器
5.2 Object:所有类的超类
- Object.equals(a,b):判断相等。
- equals:
- 特性:
- 自反性
- 对称性
- 传递性
- 一致性
- 对于任意非空引用x,x.equals(null)应该返回false。
- 编写建议:
- 显示参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量
- 检测this与otherObject是否引用同一个对象
- 检测otherobject是否为null,如果是null,返回false
- 比较this与otherObject是否属于同一个类
- 如果equals的语义在每个子类中有所改变就使用getClass检测
- 没有就使用instanceof检测
- 将otherObject转化为相应的类类型变量
- 比较需要比较的域
- 使用==比较基本类型域
- 使用equals比较对象域
- hashCode方法
- equals与hashCode的定义必须一样,比较的属性和散列的属性必须是一致的。
- toString方法
- 在调用String()的地方都可以使用"+x"来代替。
- 但是数组继承的是object的toString方法,数组类型将按照旧的格式打印,修正的方式是调用静态方法Arrays.toString
- valueOf方法:toString的逆方法。
5.3 泛型数组列表
- ArrayList是一个采用类型参数的泛型类。
5.4 对象包装器与自动装箱
- 对象包装器类是不可变的,还是final,因此不能定义它们的子类
- 自动装箱规范要求boolean、byte、char<=127,介于-128~127之间的short和int被包装到固定的对象中。
5.5 参数数量可变的方法
- 使用关键字…,表示可以接受任意数量的对象
5.6 反射
- 能够分析类能力的程序称为反射
- 机制:
- 在运行时分析类的能力
- 在运行时查看对象,例如编写一个toString方法供所有类使用
- 实现通用的数组操作代码
- 利用Method对象
5.7 继承的设计技巧
- 将公共操作和域放在超类
- 不要使用受保护的域
- 使用继承实现“is-a”关系
- 除非所有继承的方法都有意义,要不不要使用继承
- 在覆盖方法时,不要改变预期的行为
- 使用多态,而非类型信息
- 不要过多的使用反射
第六章 接口、Lambda表达式与内部类
6.1 接口
- 类实现一个接口
- 将类声明为实现给定的接口
- 对接口中的所有方法进行定义
- 接口声明的时候默认所有的方法都是public,可以不声明,但是在实现类的时候必须将方法声明为public。
- 接口的特性
- 接口不是类,不能通过new来实例化
- 可以声明接口的变量
- 接口变量必须引用实现了接口的类对象
- 接口中不能包含实例域或静态方法,但可以包含常量。
- 接口中的方法被自动设置为public,接口中的域被自动设为public static fianl。
- 1.8以后可以在接口类中增加静态方法
- 解决默认方法冲突
- 超类优先:如果一个超类提供了一个具体方法,同名且有相同参数类型的默认方法会被忽略
- 接口冲突:如果一个超接口提供了一个默认方法,另一个接口提供了一个同名且参数类型不同的方法,必须覆盖这个方法来解决冲突
- 类优先原则:一个类扩展了一个超类且同时实现了一个接口,并且从超类和接口继承了相同的方法,这种情况下只会考虑超类方法,接口的所有默认方法都会被忽略
6.2 Lambda表达式
- 例子:
import javax.swing.*;
import javax.swing.Timer;
import java.util.*;
public class promble{
public static void main(String[] args) {
String[] planets= new String[]{"sdad","sdadasd","dasda","adasdaw","dawqfaf"};
System.out.println(Arrays.toString(planets));
System.out.println("Sorted in dictionary order:");
Arrays.sort(planets);
System.out.println(Arrays.toString(planets));
System.out.println("Sort by length:");
Arrays.sort(planets,(first,second)->first.length()-second.length());
System.out.println(Arrays.toString(planets));
Timer t =new Timer(1000, event->
System.out.println("The time is" + new Date()));
t.start();
JOptionPane.showMessageDialog(null,"dadasd?");
System.exit(0);
}
}
- 函数式接口
- 对于只有一个抽象方法的接口,需要这种接口的对象是,就可以提供一个lambda表达式,这种接口就是函数式接口
6.3 内部类
- 用途:
- 内部类可以访问该类定义所在的作用域中的数据,包括私有的数据
- 内部类可以对同一个包中的其他类隐藏起来
- 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷
- 内部类中声明的所有静态域都必须是fianl。
6.4 代理
- 代理类可以在运行时常见全新的类,这样的代理类能够实现指定的接口。尤其是具有下列方法:
- 指定接口所需的全部方法
- Object类中的全部方法,例如:toString、equals等
- 创建代理对象,需要使用Proxy类的newProxyInstance方法,其参数:
- 一个类加载器
- 一个Class对象数组,每个元素都是需要实现的接口
- 一个调用处理器
- 代理类的特性
- 是在程序运行时创建的,一旦被创建就变成了常规类
- 所有代理类都扩展于Proxy类,一个代理类只有一个实例域。
第七章 异常、断言和日志
7.1 处理错误
- 异常分类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmV89GjJ-1582015998643)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200211142437.png)]
- Error:Java运行时系统内部错误和资源耗尽错误。
- Exception
- RuntimeException
- 错误的类型转化
- 数组访问越界
- 访问null指针
- 其他
- 试图在文件尾部后面读取数据
- 试图打卡一个不存在的文件
- 试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在
- 声明受查异常:
- 以下情况需抛出异常
- 调用一个抛出受查异常的方法
- 程序运行过程中发现错误,并且利用throw语句抛出一个受查异常
- 程序出现错误
- java虚拟机和运行时库出现的内部错误
- 创建异常类
- 定义一个派生于Exception的类,或者派生于Exception子类的类。应该包含两个构造器,一个是默认构造器一个是带有详细描述信息的构造器
class FileFormatException extends IOException{
public FileFormatException(){}
public FileFormatException(String gripe){
super(gripe);
}
}
- 现在就可以抛出自己定义的异常类型了
String readData(BufferedReader in) throw fileFormatException{
...
while(...){
if(ch==1){
if(n<len)
throw new FileFormatException();
}
...
}
return s;
}
7.2 捕获异常
- 想要捕获一个异常,必须设置try/catch语句块
try{
}
catch(ExceptionType e){
}
- 如果在try语句块中的任何代码抛出了一个在catch子句中说明的异常类那么:
- 程序将跳过try语句块的其他代码
- 创徐将执行catch子句中的处理器代码
- 没有异常,将不执行catch
- 如果抛出一个未声明的异常类型,那么方法会立即退出
- 如果想传递一个异常,就必须在方法的首部添加一个throws说明符,告知调用者这个方法可能会抛出异常
- finally要是包含return语句时,在方法返回前会执行finally子句,将会覆盖返回值
7.3 使用异常机制的技巧
- 异常处理不能代替简单的测试
- 不要过分地细化异常
- 利用异常层次结构
- 不要压制异常
- 在检查错误时,苛刻要比放任好
- 不要羞于传递异常
7.4 记录日志
- 基本日志:使用全局日志记录器,并调用info方法
- 高级日志:调用getLogger方法创建或获取记录器
private static final Logger myLogger =logger.getLogger("com.mycompany.myapp");
注意:未被任何变量引用的日志记录器都可能被垃圾回收。所以用一个静态变量存储日志记录器的一个引用
- 日志级别
- SEVERE
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINSET
第八章 泛型程序设计
8.1 好处
- 使代码有更好的可读性和安全性
8.2 定义简单泛型类
- 类型变量使用大写形式:使用E表示集合的元素类型,K和V分别表示标的关键字和值类型,T、U、S表示任意类型
8.3 泛型方法
- 当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型。
public class promble {
public static <T> void getamx(T a){
System.out.println(a);
}
public static void main(String[] args) {
getamx("dasda");
promble.<String>getamx("sdadada");
}
}
8.4 类型变量的限定
- 可以通过对类型变量T设置限定
public static <T extends Comparable> T min(T[] a)
8.5 泛型代码和虚拟机
- 虚拟机中没有泛型,只有普通的类和方法
- 所有的类型参数都用它们的限定类型替换
- 桥方法被合成来保持多态
- 为保持类型安全性,必要时插入强制类型转换
8.6 约束与局限性
- 不能用基本类型实例化类型参数
- 运行时类型查询只适用于原始类型
- 不能创建参数化类型的数组
- Varargs警告
- 不能实例化类型变量
- 不能构造泛型数组
- 泛型类的静态上下文中类型变量无效
- 不能抛出或捕获泛型类的实例
- 可以消除对受查异常的检查
- 注意擦除后的冲突
8.7 通配符类型
- 通配符类型中,允许类型参数变化
- Pair<? extends Employee>
- 通配符的超类型限定,可以指定一个超类型限定
- 无限定通配符
8.8 反射和泛型
- 泛型Class类
- 使用Class参数进行类型匹配
- 虚拟机中的泛型类型信息
第九章 集合
9.1 Java集合框架
- 将集合的接口与实现分离
- Collection接口:基本接口
- 基本方法:
- add()添加元素
- Iterator():用于返回一个实现类Iterator接口的对象
- 集合框架中的接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bh6D39Wj-1582015998644)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200218095021.png)]
9.2 具体集合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sd6bm9sg-1582015998644)(C:\Users\sunmingzhi\AppData\Roaming\Typora\typora-user-images\1581990667813.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vP7FYVy-1582015998645)(C:\Users\sunmingzhi\AppData\Roaming\Typora\typora-user-images\1581990690157.png)]
具体见博客
9.3 映射
- Java库中HashMap和TreeMap都实现了Map接口,如果不需要按照排列顺序访问键,就最好选择散列
第十章 并发
10.1 线程
- 不要调用Thread类或者Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,而不会启动新线程。应该调用Thread.start方法,这个方法将创建一个执行run方法的新线程
10.2 线程中断
- interrupt()方法可以用来请求终止线程,当调用时线程的中断状态将被置位,但是当线程被阻塞就无法坚持中断状态。中断一个线程不过是引起它的注意,被中断的线程可以决定如何响应中断
10.3 线程状态
- 线程的六种状态:可以使用getState查看
- New新建
- Runnable可运行
- Blocked被阻塞
- Waiting等待
- Timed waiting计时等待
- Terminated被终止
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1pW9vKF0-1582015998645)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200218102126.png)]
10.4 线程属性
- 线程优先级
- 守护线程
- 未捕获异常处理器
10.5 同步
- 有两种机制防止代码块受并发访问的干扰,synchronized关键字打到这一目的,并且Java SE 5.0 引入ReentrantLock类。其保护代码块的基本结构:
myLock.lock();
try{
}
finally{
myLock.unlock();
}
其保证了任何时刻只有一个线程进入临界区。
- 监视器特性:
- 监视器值包含私有域的类
- 每个监视器类的对象只有一个相关锁
- 使用该锁对所有的方法进行加锁
- 该锁可以有任意多个相关条件