JAVA基础知识007异常

throws关键字抛出的异常谁去处理?
使用throws关键字是将异常向上抛,抛给上一级调用者去处理,如果此时抛出的异常是一个编译时期的异常,上一级也只有两种选择:1.继续向上抛;2.使用trycatch处理掉

throw关键字用于手动抛出异常对象。 throw new 异常();
如果抛出的异常是一个运行时期的异常,可处理可不处理;
如果抛出的异常是一个编译时期的异常,必须处理。
可以在创建异常的时候,通过有参构造方法传入异常信息

throws和throw的区别
throws用在方法声明后面,跟的是异常类名;可以跟多个异常类名,用逗号隔开;表示抛出异常,由该方法的调用者来处理;throws表示出现异常的一种可能性,并不一定会发生这些异常。
throw用在方法体内跟的是异常对象名;只能抛出一个异常对象名;表示抛出异常,由方法体内的语句处理;throw表示抛出了异常,执行throw则一定是抛出了某种异常。

finally什么时候被执行
finally的作用就是为了保证无论出现什么情况,finally块里面的代码一定会被执行。由于程序执行return就意味着结束对当前函数的调用并跳出函数体,因此任何语句要执行都只能在return前执行(除非碰到exit函数),因此finally块里的代码也是在return前执行的。

public static int testFinally() {
		try {
			return 1;
		}catch(Exception e) {
			return 0;
		}finally {
			System.out.println("execute finally");
		}
}
public static void main(String[] args) {
		int result=testFinally();
		System.out.println(result);
}
程序输出:
execute finally
1

如果try-finally或者catch-finally中都有return,那么finally中的return会覆盖别处的return。

public static int testFinally() {
		try {
			return 1;
		}catch(Exception e) {
			return 0;
		}finally {
			System.out.println("execute finally");
			return 2;
		}
		
	}
程序输出:
execute finally
2

由于在一个方法内部定义的变量都存储在栈中,当函数结束后,其对应的栈就会被回收,此时在方法体中定义的变量就不存在了,因此return在返回时不是直接返回变量的值,而是复制一份,然后返回。因此对于基本类型的数据,在finally块中改变return的值对返回值没有任何影响,而对于引用类型的数据会有影响。

public static int testFinally1() {
		int result=1;
		try {
			result=2;
			return result;
		}catch(Exception e) {
			return 0;
		}finally {
			result=3;
			System.out.println("execute finally");
		}
		
	}
程序输出:
execute finally
2	
public static StringBuffer testFinally2(){
		StringBuffer s=new StringBuffer("hello");
		try {
			return s;
		}catch(Exception e) {
			return null;
		}finally {
			s.append("world");
			System.out.println("execute finally2");
		}
		
}
程序输出:
execute finally2
helloworld

程序在执行到return时会首先将返回值存储在一个指定的位置,然后去执行finally块,最后在返回。因为s为引用类型所以修改s时操作的是同一个地址的内容,将会修改程序的返回结果。
出现在java程序中的finally块是不是一定会被执行
答:不一定
case1:当程序在进入try语句块之前就出现异常时,会直接结束,不会执行finally块中的代码。
case2:当程序在try块中强制退出时也不会去执行finally块中的代码。
(System.exit(0)强制退出)
java提供了两种错误的异常类,分别为Error和Exception,其共同的父类为java.lang.Throwable。
运行时异常和普通异常

  • Error表示程序在运行期间出现了严重的错误,并且该错误是不可恢复的,由于这属于JVM层次的严重错误,因此这种错误是会导致程序终止执行的。编译器不会检查Error是否被处理,因此在程序中不推荐去捕获ERROR类型的异常,主要原因是运行时异常多是由逻辑错误导致的,属于应该解决的错误。即一个正确的程序是不应该存在Error的。
  • Exception表示可恢复异常,是编译器可以捕捉到的。包括检查异常和运行时异常。

Exception
**检查异常:**检查异常时在程序中经常碰到的异常。所有继承自Exception并且不是运行时异常的都是检查异常,比如IO异常和SQL异常。这种异常都发生在编译阶段,java编译器强制程序去捕获此类型的异常,即把可能会出现异常的代码放在try块中,把对异常处理的代码放在catch块中。这种异常一般在如下几种情况使用。

  • 异常的发生不会导致程序出错,进行处理后可以继续执行后续的操作,例如当数据库连接失败后可以重新连接进行后续操作。
  • 程序依赖于不可靠的外部条件,例如系统IO。

**运行时异常:**编译器没有强制对其进行捕获并处理。如果不对这种异常处理,当出现这种异常时会由jvm来处理。最常见的运行时异常:空指针异常、类型转换、数组越界、数组存储、缓冲区异常、算术异常等。出现运行时异常后,系统会把异常一直往上层抛,知道遇到处理代码为止。若没有处理块,则抛到最上层;如果是多线程就用Thread.run方法抛出,如果是单线程就用main方法抛出。抛出之后如果是线程,那么这个线程也就退出了。如果是主程序抛出的异常,那么整个程序也就退出了。所以如果不对运行时的异常处理,后果是非常严重的,一旦发生要麽是线程终止,要麽是主程序终止。
异常处理注意的问题

  • 进行异常捕获时,先捕获子类,再捕获基类。
  • 尽早抛出异常,同时对捕获的异常进行处理,或者从错误中恢复,或者让程序继续执行。但也不是抛出异常越多越好,对应有些异常类型比如运行时异常,实际上根本不必处理。
  • 可以根据需要自定义异常类,只要继承自Exception类即可
  • 异常能处理就处理,不能处理就抛出。对于一般异常,如果不能进行行之有效的处理,最后转换为运行时异常抛出。对于最终没处理的异常,jvm会进行处理。

try-catch后面的语句可以继续执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值