第15章 异常
要创建一个稳健的系统,每个组件都必须是稳健的。
异常处理的实现一直都有。
基本的异常:
异常情形是指阻止当前方法或作用域继续执行的问题。
在Java中可以主动抛出异常,例如,下面不带参数和带参数的
throw new NullPointerException();
// 或者
throw new NullPointerException("异常信息");
捕捉异常
Java使用try- catch块进行指定范围的异常捕获
try{
// 划分定的代码块
}catch(NullPointerException e){
// 捕获制定类型的异常
}catch(NumberFormatException e){
//
}
创建自己的异常
要求我们编写自己的异常类,并且该类要继承指定类型的异常,一般都是继承Exception类
被捕获的类型的异常对象使用e.printStackTrace(),可将异常信息打印到日志中。
public class MyException extends Exception {
public MyException(){
super();
}
}
异常说明:
在定义接口和方法时,可将指定类型的异常信息抛出,这也就是告诉了使用接口或调用方法的一方这里会有该类型异常抛出,要针对处理。
捕捉任何异常
通过捕获异常的基类Exception实现任何类型异常的捕获。所以代码中指定类型的异常进行捕获,除了这个类型异常,所有继承这个异常的子异常都会被捕获住。
一个catch里可以写多个类型异常,进行捕获,简化代码;
也可以在catch里对捕获到的指定类型的异常进行二次的异常抛出,此时抛出的异常类型,和catch的类型可以不一样。
使用finally执行清理
finally的作用是强制在finally块里的代码,都会在return之前执行。
try{
}catch(MyException e){
}catch(Exception e){
}finally{
}
try{
}finally{
}
构造器
在类构造器里如果抛出异常,会导致有些清理行为不会正确执行。
try-with-resources语句
这个语句要求实现AutoCloseable接口的类使用,因为它把方法的close方法内部封装了,程序员就不用手动编写close方法。
第16章 代码校验
测试
如果没有经过测试,代码就不可能正常工作。
单元测试,一般使用JUnit。
测试覆盖率,也称为代码覆盖率,是衡量代码库的测试百分比。
前置条件
前置条件概念来自契约式设计,并使用了基本的断言机制来实现。
断言通过验证程序执行期间是否满足某些条件来提高程序的稳健性。
Java的断言,使用assert语法。
assert boolean-expression
assert boolean-expression:information-expression
测试驱动开发
前提是在设计和编写代码时考虑到测试,不仅会创建可测试的代码,而且代码的设计会变得更好。
可以先在测试用例里指明所有要实现的功能,然后以此为起点,在代码中实现相关功能,直到所有测试都通过。
日志
日志会报告正在运行的程序的相关信息。
SLF4J为多个日志框架提供了一个统一的门面。
日志级别,从低到高分别是trace、debug、info、warn、error。
调试
使用编辑器开发工具对编写的代码逐行运行,并查看当前行的运行结果是否符合要求。
分析和优化
分析程序运行耗时的部分,然后解决耗时提高速度。
优化指南:
- 避免为了性能而牺牲代码的可阅读性
- 不要孤立的看待性能。权衡付出的努力与获得的好处。
- 程序大小很重要。性能优化通常只对长时间运行的大型项目有价值。小型项目通常不需要关心性能。
- 让程序先正常工作比努力提高其性能更重要。
- 不要猜测性能瓶颈在哪,要学会使用分析器。
- JVM会优化static final变量来提高程序速度。
样式检查
在一个团队中要统一代码编写风格和样式。
静态错误分析
使用分析工具分析代码的基本语法错误。
重构
技术债务是那些在软件中积累的快速而肮脏的解决方案,它使设计无法理解,代码无法阅读,当你必须改正或添加功能时,就会有问题。
重构是技术债务的解毒剂,重构会改进代码设计、结构和可读性,但它不会改变代码的行为。
重构的基础:
- 测试
- 构建自动化,从而容易构建代码并运行所有测试。
- 版本控制,这样就可以随时提供或回退到可工作的代码版本。
第17章 文件
文件或目录的路径
Path对象代表的是一个文件或目录的路径,它是在不同的操作系统和文件系统之上的抽象。
java.nio.file.Paths类包含了重载的 static get()方法。
选择Path的片段
- Path可以生成Iterator,也就是Path可以for循环。
- 要在一个Path对象的后面增加路径片段,要使用resolve方法;去掉Path这个基准路径,使用relativize方法。
Files工具类提供了多个访问目录并进行操作的方法。
- walkFileTree,查找每个子目录和文件,也就是遍历
- preVisitDirectory,先在当前目录上运行,然后进入这个目录下的文件和目录
- visitFile,在这个目录下的每个文件上运行
使用FileSystem表示文件系统的工具类,也可以通过Path生成一个FileSystem
使用WatchService能够设置一个进程,对某个目录中的变化做出反应。
通过在FileSystem对象上调用getPathWatcher方法来获得一个PathWatcher,用来进行文件查找。
Files.readAllLines方法读取整个文件,并转成List。
Files.lines将一个文件转成一个stream。