前言:
Java通过API中的Throwable类的众多子类描述各种不同的异常,所以java异常是Throwable子类的实例化对象。Throwable有两个重要的子类:Exception和Error。
Error
Error错误代表了程序运行时Java系统内部的错误,与程序设计者的操作无关。 Error是不可查的 。
Exception
是程序本身可以处理的异常,程序设计者应尽量加以处理的部分。
Exception分为两类,一类是:运行时异常(RuntimeException)另一类是编译时异常(书上写的可称非运行时异常或已检查异常,是因为在Exception类中的子类只有RuntimeException是运行时异常。)
RuntimeException也是不可查异常。
- 常见的运行时异常(虽然编译也能通过,但是还是需要我们处理避免出现这些异常。)
ArrayIndexoutofBoundsException | 访问数组时使用无效索引值 |
---|---|
NullPointException | 尝试访问null对象成员,空指针异常 |
ClassCastException | 类型转换异常 |
ArithmeticException | 非法的算术运算,如以0作除数 |
NumberFormatException | 数字转化格式异常 |
IllegalArgumentException | 方法接收到非法参数 |
try - catch -finally的学习
一般例子为:
try {
//可能出现异常的代码
}catch(异常类型1 变量名1) {
//处理异常的方式1
}catch(异常类型2 变量名2) {
//处理异常的方式2
}
....
finally {
//一定会执行的代码
}
1.执行try(catch)中的return,看看finally的顺序
public static int Sum() {
int num;//这里把num的定义写在了try和finally的外部,num指向的就是一个了。
try {
num = 10;
System.out.println(num);
num = 30;
return num;
} finally {
num = 20;
System.out.println("finally的num:"+num);
}
}
public static void main(String[] args) {
System.out.println(Sum());
}
输出为:
10
finally的num:20
30
通过上面两个例子可以了解到:try ,finally 语句是顺序执行的,不过try块区域的return是最后再return输出的。也就是会执行完Finally再return。
2.执行try(catch)中的return 且 return为方法,看看finally的顺序
//写一个含try和finally的方法类型为String(为了后续输出对应。)
public static String Fun() {
try {
System.out.println("try");//----------1
return FunctionM();//进入这个方法中。
} finally {
System.out.println("finally");//-------------4
}
}
//用try来调用FunctionM方法看输出顺序如何?
public static String FunctionM() {
System.out.println("FunctionM方法中的输出语句。");//--------2
System.out.println(FunctionN("成功在return “pz” 前输出"));//----------3
//顺序执行。
return FunctionN("pz");//-------------5
}
//通过上一步方法来继续return一个方法,进一步测试输出顺序。
public static String FunctionN(String name) {
return name;
}
public static void main(String[] args) {
System.out.println(Fun());
}
输出为:
try
FunctionM方法中的输出语句。
成功在return “pz” 前输出
finally
pz
可以发现,语句是按顺序执行,如果遇到了return,会进去执行其中的方法语句,执行到遇到return为止。然后跳到finally语句中输出,再return最后调用得到的数据。(如果return为方法的话)。
3.执行try(catch),如果在finally语句中添加一个return语句的话。
public static String Fun() {
try {
System.out.println("try");
return FunctionM();
} finally {
System.out.println("finally");
return "lxm";
//区别就是这里加上了一句return。
}
}
public static String FunctionM() {
System.out.println("FunctionM方法中的输出语句。");
System.out.println(FunctionN("成功在return “pz” 前输出"));
return FunctionN("pz");
}
public static String FunctionN(String name) {
return name;
}
public static void main(String[] args) {
System.out.println(Fun());
}
输出为:
try
FunctionM方法中的输出语句。
成功在return “pz” 前输出
finally
lxm
结论:当finally有返回值时,会直接返回。不会返回try或catch中的返回值或返回方法的返回值。
4.当finally对变量做修改是否影响返回值
public static int show() {
int a = 10;
try {
System.out.println(a + " 我是try");
return a;
} catch (Exception e) {
return 2;
} finally {
System.out.println("finally模块被执行");
a = 0;
System.out.println(a);
}
}
public static void main(String args[]) {
System.out.println("main:"+show());
}
输出为:
10 我是try
finally模块被执行
0
main:10
结论:try或catch的return是一个变量,函数的是从两个之中返回时,后面finally中语句有对返回的变量进行赋值的操作时,不会影响返回的值,可以认为返回的值延迟到FINALLY执行后再返回。
5.当finally对变量做修改不影响返回值,但是否影响变量的值
public class Demo{
static int num;
public static int Sum() {
//这里把num的定义写在了try和finally的外部,num指向的就是一个了。
try {
num = 10;
System.out.println(num);
num = 30;
return num;
}catch (Exception e) {
e.printStackTrace();
num = 222;
return num;
}finally {
num = 20;
System.out.println("finally的num:"+num);
}
}
public static void main(String[] args) {
System.out.println("main:"+Sum());
System.out.println("Demo.num"+Demo.num);
}
}
输出为:
10
finally的num:20
main:30
Demo.num20
结论:try或catch的return是一个变量,函数的是从两个之中返回时,后面finally中语句有对返回的变量进行赋值的操作时,不会影响返回的值,但是会影响静态变量num,也就是会影响变量num。假如一些输入流输出流,可以在finally区域块把它们close,因为finally会影响最终的变量,但是不影响try(catch)返回结果,可以说try,catch结果的return虽然在finally后面执行,但是该结果的值要返回的值已经在finally执行前保存到内存,等到执行完finally后,再执行返回保存在内存的值(不受finally影响)。