Java中的异常

Posted 张同学吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的异常相关的知识,希望对你有一定的参考价值。

异常

初识异常

在我们之前遇到的代码中,多多少少都会有报错的情况,就比如:数组越界、除数为0、指针为空等情况。所谓异常指的就是程序在 运行时 出现错误时通知调用者的一种机制。
和编译期的错误不一样,编译时出错一般是指拼写错误,语法错误。而运行时指的是程序已经编译通过了,得到了class文件再由JVM执行过程中出现的错误。

异常的基本用法

基本语法

使用 try 和 catch 关键字可以捕获异常,try/catch代码块中的代码称为保护代码,可以放在异常可能发生的地方,具体用法如下:

try

   //有可能出错的程序代码
catch(ExceptionName e1)

   //Catch 块
finally 
	异常的出口

try 代码块中放的是可能出现异常的代码.
catch语句包含要捕获异常类型的声明。catch 代码块中放的是出现异常后的处理行为.
finally 代码块中的代码用于处理善后工作, 会在最后执行.
其中 catch 和 finally 都可以根据情况选择加或者不加.

基本用法

1.使用try catch捕捉异常

int[] arr = 1, 2, 3;
try 
	System.out.println("before");
	System.out.println(arr[100]);
	System.out.println("after");
 catch (ArrayIndexOutOfBoundsException e) 
	// 打印出现异常的调用栈
	e.printStackTrace();

System.out.println("after try catch");
// 执行结果
before
java.lang.ArrayIndexOutOfBoundsException: 100
	at demo02.Test.main(Test.java:10)
after try catch

当保护代码块中发生一个异常时,那么 try 代码块中的程序就不会继续执行, 而是交给 catch 中的代码来执行. catch执行完毕会继续往下执行.。

2.catch 只能处理对应种类的异常
比如:

int[] arr = 1, 2, 3;

try 
	System.out.println("before");
	arr = null;
	System.out.println(arr[100]);
	System.out.println("after");
 catch (ArrayIndexOutOfBoundsException e) 
	e.printStackTrace();

System.out.println("after try catch");

这段程序代码的执行结果会仍然报错,因为catch所捕捉的错误类型与try中的错误类型不匹配,所以没有捕捉到。
3.**catch可以有多个**
例如

```java
catch (ArrayIndexOutOfBoundsException e) 
	System.out.println("这是个数组下标越界异常");
	e.printStackTrace();
 catch (NullPointerException e) 
System.out.println("这是个空指针异常");
	e.printStackTrace();

/*一段代码可能会抛出多种不同的异常, 不同的异常有不同的处理方式. 因此可以搭配多个 catch 代码块.
如果多个异常的处理方式是完全相同, 也可以写成这样*/
catch (ArrayIndexOutOfBoundsException | NullPointerException e) 
	...

由于 Exception 类是所有异常类的父类. 因此可以用这个类型表示捕捉所有异常
如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。也可以进行多重捕获,具体用法是在try代码块后面跟随多个catch代码块。
4.finally 表示最后的善后工作, 例如释放资源
catch 语句往往是和finally配合使用,finally关键字用来创建在try代码块后面执行的代码块,无论是否发生异常,finally代码块中的代码总会被执行,因此,在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
但你也可以在try中就直接回收资源:

try (Scanner sc = new Scanner(System.in)) 
	int num = sc.nextInt();
	System.out.println("num = " + num);
 catch (Exception e) 
	e.printStackTrace();

这样一来scanner。close会直接在try执行完毕后自动调用。
5.如果本方法中没有合适的处理异常的方式, 就会沿着调用栈向上传递,如果向上一直传递都没有合适的方法处理异常, 最终就会交给 JVM 处理, 程序就会异常终止

java异常体系

  • 顶层类 Throwable 派生出两个重要的子类, Error 和 Exception
  • 其中 Error 指的是 Java 运行时内部错误和资源耗尽错误. 应用程序不抛出此类异常. 这种内部错误一旦出现,除了告知用户并使程序终止之外, 再无能无力. 这种情况很少出现.
  • Exception 是我们程序猿所使用的异常类的父类.
  • 其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类
  • NullPointerException , IndexOutOfBoundsException 等.
  • Java语言规范将派生于 Error 类或 RuntimeException 类的所有异常称为 非受查异常, 所有的其他异常称为受查异常

自定义类异常

Java 中虽然已经内置了丰富的异常类, 但是我们实际场景中可能还有一些情况需要我们对异常类进行扩展, 创建符合
我们实际情况的异常

public static void main(String[] args) 
	try 
		login("admin", "123456");
	 catch (UserError userError) 
		userError.printStackTrace();
	 catch (PasswordError passwordError) 
		passwordError.printStackTrace();
	

public static void login(String userName, String password) throws UserError,PasswordError 
	if (!Test.userName.equals(userName)) 
		throw new UserError("用户名错误");
	
	if (!Test.password.equals(password)) 
		throw new PasswordError("密码错误");
	
	System.out.println("登陆成功");

小tips:

在这里我用到了throws,throws和throw的区别在于:
throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
语法:(修饰符)(方法名)([参数列表])[throws(异常类)]…
例:public void doA(int a) throws Exception1,Exception3…
throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。
throws语句用在方法声明后面,主要是声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常。如果再抛出异常,由该方法的调用者来处理。
throw是具体向外抛异常的动作,所以它是抛出一个异常实例。

所以throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常

以上是关于Java中的异常的主要内容,如果未能解决你的问题,请参考以下文章

Java中的异常

Java异常处理的基础知识

java中的异常处理的基本结构

FIFO可能会发生Belady异常,堆栈算法不会发生Belady异常,如LRU。证明为何不会异常。

Java中的异常处理try catch(第八周课堂示例总结)

异常处理(动手动脑)