JAVA语言是如何进行异常处理的,关键字:throws、throw、try 、catch、finally分别代表什么意义? 在try块中可以抛出异常吗?
(1)程序在运行过程中发生错误或异常情况是不可避免的,如果每一个运行时错误都由程序员手动控制和处理,其工作量是不可想象的。
Java语言中的异常处理机制就解决的上述问题,把错误与异常的管理带到了面向对象的世界
(2)java异常分类
Java语言按照错误严重性,从throwale根类衍生出Error和Exception两大派系
Error(错误):程序在执行过程中所遇到的硬件或操作系统的错误。错误对程序而言是致命的,将导致程序无法运行**。常见的错误有内存溢出**,jvm虚拟机自身的非正常运行,calss文件没有主方法。程序本生是不能处理错误的,只能依靠外界干预。Error是系统内部的错误,由jvm抛出,交给系统来处理。
EXCEPTION(异常):是程序正常运行中,可以预料的意外情况。比如数据库连接中断,空指针,数组下标越界。异常出现可以导致程序非正常终止,也可以预先检测,被捕获处理掉,使程序继续运行。
EXCEPTION(异常)按照性质,又分为编译异常(可检测)和运行时异常(不可检测)。
编译时异常:又叫可检查异常,通常时由语法错和环境因素(外部资源)造成的异常。比如输入输出异常IOException,数据库操作SQLException。其特点是,Java语言强制要求捕获和处理所有非运行时异常。通过行为规范,强化程序的健壮性和安全性。
运行时异常:又叫不检查异常RuntimeException,这些异常一般是由程序逻辑错误引起的,即语义错。比如算术异常,空指针异常NullPointerException,下标越界IndexOutOfBoundsException。运行时异常应该在程序测试期间被暴露出来,由程序员去调试,而避免捕获。
所以,java语言处理运行时错误有三种方式,
一是程序不能处理的错误,二是程序应该避免而可以不去捕获的运行时异常,三是必须捕获的非运行时异常。
(3)java异常处理机制
java默认处理机制:
1抛出异常
2终止程序
异常处理程序机制:
1抛出异常
2try-catch-finally 捕获和处理异常
throw:手动抛异常
throw是语句抛出一个异常。
语法:throw (异常对象);
throw e;
throws:方法抛异常
throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
语法:(修饰符)(方法名)([参数列表])[throws(异常类)]{…}
public void doA(int a) throws Exception1,Exception3{…}
throws E1,E2,E3只是告诉程序这个方法可能会抛出这些异常,方法的调用者可能要处理这些异常,
而这些异常E1,E2,E3可能是该函数体产生的。
throw则是明确了这个地方要抛出这个异常。
void doA(int a) throws IOException,{
try{
......
}catch(Exception1 e){
throw e;
}catch(Exception2 e){
System.out.println("出错了!");
}
if(a!=b)
throw new Exception3("自定义异常");
}
try、catch、finally用法总结:
1、不管有没有异常,finally中的代码都会执行
2、当try、catch中有return时,finally中的代码依然会继续执行
3、finally是在return后面的表达式运算之后执行的,此时并没有返回运算之后的值,而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的。
4、finally代码中最好不要包含return,程序会提前退出,也就是说返回的值不是try或catch中的值
执行顺序
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3 System.out.println(test());
4 }
5 public static int test(){
6 int i = 1;
7 try{
8 i++;
9 System.out.println("try block, i = "+i);
10 }catch(Exception e){
11 i ++;
12 System.out.println("catch block i = "+i);
13 }finally{
14 i = 10;
15 System.out.println("finally block i = "+i);
16 }
17 return i;
18 }
结果输出如下:
try block, i = 2
finally block i = 10
10
先执行try块,并没有捕获到异常,finally 块,最后return。
当我们把return放到try块中和catch块中,会怎么样呢?你们会不会纠结先return呢还是先finally呢?返回值i会改变吗?
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3 System.out.println(test());
4 }
5 public static int test(){
6 int i = 1;
7 try{
8 i++;
9 System.out.println("try block, i = "+i);
10 return i;
11 }catch(Exception e){
12 i ++;
13 System.out.println("catch block i = "+i);
14 return i;
15 }finally{
16 i = 10;
17 System.out.println("finally block i = "+i);
18 }
19 }
结果输出如下:
try block, i = 2
finally block i = 10
2
如我们总结一样:
2、当try、catch中有return时,finally中的代码依然会继续执行
3、finally是在return后面的表达式运算之后执行的,此时并没有返回运算之后的值,
而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,
依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的。
如果是操作不是基本类型会怎么样?会不一样吗?为什么?
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3 System.out.println(test().mmp("fuck"));
4 }
5 public static Person test(){
6 Person person = new Person();
7 try{
8 person.setShengao("172cm"+"---try block");
9 System.out.println("try block");
10 return person;
11 }catch(Exception e){
12 person.setTizhong("100kg");
13 System.out.println("catch block");
14 return person;
15 }finally{
16 person.setXingbie("女");
17 System.out.println("finally block ");
18 }
19 }
复制代码
Person类
复制代码
1 package xyz;
2
3 public class Person {
4 public String shengao;
5 public String tizhong;
6 public String xingbie;
7
8 //public String hello(String input);
9
10 public String getShengao() {
11 return shengao;
12 }
13
14 public void setShengao(String shengao) {
15 this.shengao = shengao;
16 }
17
18 public String getTizhong() {
19 return tizhong;
20 }
21
22 public void setTizhong(String tizhong) {
23 this.tizhong = tizhong;
24 }
25
26 public String getXingbie() {
27 return xingbie;
28 }
29
30 public void setXingbie(String xingbie) {
31 this.xingbie = xingbie;
32 }
33
34
35 public String mmp(String fuck){
36 System.out.println("person : mmp");
37 System.out.println("shengao:"+this.shengao);
38 System.out.println("tizhong:"+this.tizhong);
39 System.out.println("xingbie:"+this.xingbie);
40 return fuck;
41 }
42
43 }
复制代码
结果输出如下:
try block
finally block
person : mmp
shengao:172cm---try block
tizhong:null
xingbie:女
fuck
从上面可以看出,在finally中的set的性别 女 生效了,而在之前用基本类型,在finally中修改它的值不生效。为什么呢?
我们知道基本类型在栈中存储,而对于非基本类型是存储在堆中的,返回的是堆中的地址,因此内容被改变了。
.如果在finally加入return,会怎么样? 如果在finally 抛出了异常呢?
在finally中存在return,会有黄色警告:finally block does not complete normally 意思是finally代码块不能正常完成。
在try块中可以抛出异常吗?
try {
throw new Exception();
}catch (Exception e) {
// TODO: handle exception
}
用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。
throw语句用来明确地抛出一个”异常”。
throws用来标明一个成员函数可能抛出的各种”异常”。
Finally为确保一段代码不管发生什么”异常”都被执行一段代码。
可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,”异常”的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种”异常”进行处理,堆栈就会展开,直到遇到有处理这种”异常”的try语句。