《Java 核心技术 卷1》 笔记 第11章 异常、日志、断言和调试_程序错误

出现不可预计的问题时,需要进行如下处理:

  1. 报告错误
  2. 保存操作结果
  3. 允许用户退出

本章解决的问题:

  • 验证程序正确性
  • 记录程序错误
  • 调试技巧

11.1 处理异常

程序出现错误时应该:

  • 返回安全状态,能让用户执行其他命令
  • 允许用户保存所有操作结果,并能够终止程序

程序错误的关注点:

  1. 用户输入错误
  1. 不遵循程序要求,语法不正确,程序代码应该检查,如果没有检查,会出现错误(遇到过,没检查到,提示不友好用户投诉的)
  1. 设备错误
  1. 硬件不一定能够使用,比如打印机关上了,没纸了(这个处理好IO问题不大)
  1. 物理限制
  1. 磁盘满了(遇到过,数据库太大把磁盘占满,搬数据库)
  1. 代码错误
  1. 返回了错误的答案,或者错误的调用了其他方法(必然遇到过T T)

11.1.1 异常分类

Throwable下,分为Error和Exception

Exception下,又分爲IOException和RuntimeException

Error: Java运行时的内部错误和资源耗尽错误。这种错误通常是系统宕机级别的,处理起来时间较长。(比如没有磁盘空间了)通常在代码层面无法处理这种错误。

RuntimeException: 程序本身没有问题,IO错误等

常见的运行时异常:

  1. 数组越界
  2. 空指针
  3. 类型转换错误

检查异常:

  1. 错误URL
  2. 反射异常
  3. 读取超出文件尾部的数据

所以非运行时错误,一定是编码问题

11.1.2 声明已检查异常

无法处理的情况,Java方法可以抛出一个异常,告诉编译器要返回什么值,如果没有值,则返回发生的错误。

抛出异常的情况:

(1)调用抛出异常的方法

(2)运行过程中发生错误,抛出已检查异常

(3)程序错误,提供不应该提供的数值,a[-1]=0 会报越界异常

(4)Java 虚拟机和运行库异常

前两种必须捕获,不捕获可能宕机

抛出异常的方式:

Class MyAnimation{

Pubic Image loadImage(String s) throw EOFException,MalformedURLException{}

}

异常处理方式:

捕获:进行处理,展示给用户

抛出:交给上一层级处理

不处理:不可控的Error,或者使用规则限制,不产生额外的异常

特殊要求:

子类异常范围,不能超出父类异常范围

11.1.3 如何抛出异常

假设IO读取数据时不完整,可考虑抛出IOException, API 提议抛出 EOFException

基本格式:

public [返回值] 方法名(参数列表) 抛出列表{

throw new XXException();

}

11.1.4 创建异常类

有时候,标准异常描述并不能做到清楚具体,或者无法具体定位异常原因,为了进一步了解是程序中的哪一段出现异常,可考虑建立自己的异常类(个人觉得一个是名称识别,另外异常文字之类的可以做特殊处理,让它打印到log对应级别上而非直接输出)。

class FileFormatException extends IOException{
public FileFormatException(){}
public FileFormatException(String gripe){
super(gripe);
}
}

然后就可以像IOException一样使用这种异常

public class Main {
public static void main(String[] args) throws FontFormatException {
Main solution = new Main();

solution.test(1);

}

private void test(int num) throws FontFormatException {
if(num==1)
throw new FontFormatException("test");
}
}

不传之密,异常处理工具,保留一定字数的异常信息(数据库存储大小是有限的):

public class ErrorUtil {
public static String exceptionStr(Exception e, int length) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
String exception = baos.toString();

String regEx = "Caused by:(.*)";
Pattern pat = Pattern.compile(regEx);
Matcher mat = pat.matcher(exception);
boolean rs = mat.find();
if (rs) {
if (mat.group(1).length() > length) {
return mat.group(1).substring(0, length);
} else {
return mat.group(1);
}
} else {
if (exception.length() > length) {
return exception.substring(0, length);
} else {
return exception;
}
}
}

public static String exceptionStr(Exception e){
return exceptionStr(e,800);
}

public static String getAllException(Exception e){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
String exception = baos.toString();
String regEx = "Caused by:(.*)";
Pattern pat = Pattern.compile(regEx);
Matcher mat = pat.matcher(exception);
boolean rs = mat.find();
if (rs) {
return mat.group(1);
} else {
return exception;
}
}
}

结合:

public class Main {
public static void main(String[] args) {
Main solution = new Main();

try {
solution.test(1);
} catch (FontFormatException e) {
System.out.println(ErrorUtil.getAllException(e));
}

}

private void test(int num) throws FontFormatException {
if(num==1)
throw new FontFormatException("test");
}
}

《Java 核心技术 卷1》 笔记 第11章 异常、日志、断言和调试_java_02

相关内容:选择 《Java核心技术 卷1》查找相关笔记

评论🌹点赞👍收藏✨关注👀,是送给作者最好的礼物,愿我们共同学习,一起进步

公众号 钰娘娘知识汇总