个人在学习多线程的时候做的笔记,分享出来,能和大家一起交流。
目录
getMessage()方法和printStackTrace()方法
-
异常
-
异常是程序执行过程中的不正常情况
-
异常的作用是增强程序的健壮性
-
不管是错误,还是异常,都可以抛出
-
一但错误发生,Java程序只有一个结果,就是终止程序的执行,并退出JVM。错误是不可处理的
-
所有的RuntimeException及子类都属于运行时异常。编写时可选择处理,也可以选择不处理
-
所有的ExceptionSubClass及子类都属于编译时异常。编译时异常指在编译之前必须处理好的异常,即编写时处理
-
所有异常都是发生在运行阶段
-
-
UML
-
UML是一种统一建模语言。是一种图标式语言,用来画图
-
工具:Rational Rose、starUML
-
-
异常继承结构的简单描述
-
Object
-
Object下有Throwable类(可抛出)
-
Throwable类下有两个分支
-
Error类:不可处理,直接退出JVM
-
Exception类:可处理的
-
-
Exception类下有两个分支
-
Exception类:该类及其直接子类:编译时异常,要求程序员在编写阶段必须预先对这些异常进行处理,不处理时编译器会报错
-
RuntimeException类:运行时异常
-
-
-
异常的其他名字:
-
编译时异常的其他名字:受检异常、受控异常
-
运行时异常的其他名字:未受检异常、未受控异常
-
-
处理异常的两种方式
-
方式一:throws关键字
-
在方法的声明位置上,使用throws关键字将异常抛给上一级,由上一级处理。可一层层上抛,最高级是JVM,可由main方法上抛给JVM,JVM出现异常就会停止。所以在main方法中不建议使用throws
-
-
方式二:try...catch语句进行异常捕捉
-
捕捉异常并处理异常
-
-
-
try...catch代码执行情况
-
只要异常采用的是抛出的方式,没有捕捉,此方法后续的代码不会执行;需要捕捉后,后续代码才会执行
-
try语句块中某一行出现异常,该行后面的代码不会执行
-
一个方法体当作的代码出现异常,采用上报的形式的话,则该方法结束
-
-
深入try...catch
-
catch后面的小括号中的类型可以是异常类型,也可以是该异常类型的父类型
-
catch可以写多个。建议在catch时,精确的一个一个地处理,这样有利于程序的调试
-
catch写多个时,从上到下,必须遵守从小到大的原则
-
在catch中,创建的异常对象的地址会赋给e,通过e来使用异常对象
-
-
异常中的关键字
-
异常捕捉
-
try
-
catch
-
finally
-
-
抛出异常
-
throws:在方法声明位置上使用,表示上报异常信息给调用者
-
throw:手动抛出异常
-
-
-
getMessage()方法和printStackTrace()方法
-
String msg = exception.getMessage():获取异常简单的描述信息
-
exception.printStackTrace();(建议):打印异常追踪的堆栈追踪信息
-
代码展示
-
package com.bjpowernode.javase.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ExceptionTest08 {
public static void main(String[] args) {
// 这里new的异常对象,没有将异常抛出,JVM会认为该异常对象是普通的Java对象
NullPointerException e = new NullPointerException("空指针异常啊");
// getMessage()方法获取异常简单描述信息,这个描述信息是构造方法上面的String参数
String msg = e.getMessage();
System.out.println(msg);
// 打印异常堆栈追踪信息。后台打印的时候,采用的是异步线程的方式打印
e.printStackTrace();
try {
m2();
} catch (FileNotFoundException ex) {
ex.printStackTrace();// 打印异常追踪的堆栈追踪信息,建议使用
}
}
private static void m2() throws FileNotFoundException {
System.out.println("m2 begin");
// 创建一个输入流对象,该流指向一个文件
new FileInputStream("E:\\IOliu_ceshi\\temp.txt");
System.out.println("m2 over");
}
}
-
finally子句
-
在finally子句中的代码在最后执行,而且是一定会执行,无论try中是否出现异常都会执行
-
finally子句必须和try一起出现,不能单独编写,可以没用catch语句
-
通常finally语句块中完成资源的释放或关闭。因为finally中的代码一定执行(除非finally之前退出了JVM),所以有保障
-
执行顺序:try--->catch--->finally
-
注意:finally之前退出了JVM,便不会执行finally
-
代码展示
-
package com.bjpowernode.javase.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest10 {
public static void main(String[] args) {
// 创建输入流对象。在try前面创建输入流对象,这样在finally中才能调用
FileInputStream fis = null;
try {
// 创建输入流对象
fis = new FileInputStream("E:\\IOliu_ceshi\\temp.txt");
String s = null;
// 这里会出现空指针异常
s.toString();
// 上面出现空指针异常,则前面的代码不会继续执行,便不会输出
System.out.println("hello world!");
// 在这里关闭流的话,如果前面出现异常则不能正常关闭
// fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("finally执行啦");
// 关闭流。finally中的代码一定执行,所以一定会关闭流
if (fis != null) {// 避免空指针异常
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
-
代码展示:提前退出JVM,使finally不执行
package com.bjpowernode.javase.exception;
public class ExceptionTest12 {
public static void main(String[] args) {
try{
System.out.println("try……");
// 退出JVM
System.exit(0);
}finally {
// try中退出了JVM,则finally不会执行,不会输出
System.out.println("finally……");
}
}
}
-
finally面试题
-
Java语法规则1:方法体中的代码必须是自上而下的顺序依次执行(亘古不变), 所以是先返回i=100,再i++,所以输出的是100
-
Java语法规则2:return语句一旦执行,整个方法必须结束(亘古不变)
-
题目:输出什么值?
-
package com.bjpowernode.javase.exception;
public class ExceptionTest13 {
public static void main(String[] args) {
int result = m();
System.out.println(result);// 问题:会输出什么值
}
public static int m(){
int i = 100;
try{
return i;
} finally {
i++;
}
}
}
-
m()方法反编译:
-
用临时变量保存i值,然后返回i值。既保证了return的值是i=100,又执行了i++
-
// 上面m方法反编译。用临时变量保存i值,然后返回i值
public static int m(){
int i = 100;
int j =i;
i++;
return j;
// 下面这些不用看
Exception exception;
exception;
i++;
throw exception;
}
-
final、finally、finalize的区别
-
final:final是一个关键字,表示最终的,不变的
-
finally:finally是一个关键字,和try联合使用,使用在异常处理机制中。finally语句块中的代码一定会执行
-
finalize:finalize是一个标识符。finalize()是Object类中的一个方法,作为方法名出现,这个方法是对象被回收之前执行
-
-
自定义异常
-
自定义异常分两步:
-
编写一个类继承Exception或者RuntimeException
-
提供两个构造方法,一个是无参构造方法,另一个是带头=有String参数的构造方法
-
-
代码展示:
-
创建自定义异常类
-
-
package com.bjpowernode.javase.exception;
public class MyException extends Exception {
public MyException(){
}
public MyException(String s){
super(s);
}
}
-
自定义异常类的使用
package com.bjpowernode.javase.exception;
public class ExceptionTest15 {
public static void main(String[] args) {
// 创建异常对象(只new了异常对象,并没有抛出异常)
MyException e = new MyException("用户名不能为空");
// 打印异常堆栈信息
e.printStackTrace();
// 获取异常简单描述
String msg = e.getMessage();
System.out.println(msg);
}
}