Java异常
1异常介绍
1.1异常的发生
异常是在什么时候发生的呢?
我们在自定义异常的时候,通常需要throw new Exception(),这说明了什么?----这充分说明了异常是在运行时发生的,因为只有在运行时可以new对象。
package com.fq.OnClass519;
public class MyException extends Exception{
public MyException() {
}
public MyException(String message) {
super(message);
}
public void run() throws MyException {
throw new MyException("我自定义的异常!!!!!!!!!!!");
}
}
package com.fq.OnClass519;
public class Main {
public static void main(String[] args) {
MyException exception = new MyException();
try{
exception.run();
}catch (Exception e){
e.printStackTrace();
}
}
}
/*
抛异常
com.fq.OnClass519.MyException: 我自定义的异常!!!!!!!!!!!
at com.fq.OnClass519.MyException.run(MyException.java:12)
at com.fq.OnClass519.Main.main(Main.java:7)
*/
从这段自定义异常中我们可以看到,抛出的异常都是对象
1.2异常的分类
异常分为编译时异常和运行时异常,但是编译时异常发生在编译的时候吗?
不对,我们刚刚说过了,异常都是发生在运行的时候,因为异常也是对象,只有运行的时候才能创造对象
有时候我们又会看到受检异常,或者受控异常这样的说法:
受检异常: 指异常在编译时被 Java 编译器检测到(就是我们所说的编译时异常)
非受检异常:指异常只能在程序运行时才能被检测到,包括 **运行是异常(Runtime Exception)**和 错误(Error)
既然提到了Error,我们也来了解一下吧
1.3Error
Error和Exception都继承自Throwable在Java代码中只有继承了 Throwable 类的实例才能被 throw 或者 catch。
Exception 是程序正常运行过程中可以预料到的意外情况,并且应该被开发者捕获,进行相应的处理。Error 是指正常情况下不大可能出现的情况,绝大部分的 Error 都会导致程序处于非正常、不可恢复状态。所以不需要被开发者捕获。
Error 错误是任何处理技术都无法恢复的情况,肯定会导致程序非正常终止。Error也是非受检异常。
2异常的处理
我们发生异常的情况很多
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字");
int a = scanner.nextInt();
System.out.println(a);
}
/*
请输入数字
1
1
*/
如果我们正常输入,倒是没事,正常运行
但是如果我们输入的不是int类型的呢?
比如我们输入一个a
a
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at com.fq.OnClass519.New.main(New.java:17)
Process finished with exit code 1
直接报异常
但是我们不能因为这一点小的异常就直接把程序结束掉吧,试想,一个人只是有一点小感冒,你却要终结他的生命,这合理吗?
因此,我们因该用一种方法来保证程序即使出现了小的错误,小的异常,也要让它继续运行,不能就这样结束了。
于是我们使用try
和catch
来解决这种问题。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字");
try{
int a = scanner.nextInt();
}catch (InputMismatchException e){
e.printStackTrace();
}
System.out.println("还没有结束!!!!!!!!!");
}
/*
请输入数字
a
java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at com.fq.OnClass519.New.main(New.java:12)
还没有结束!!!!!!!!!
Process finished with exit code 0
*/
我们可以看到最后返回值为0,程序正常结束,最后一句话也打印出来了,程序并没有直接结束。
3补充
关于异常和Main
public static void main(String[] args) {
System.out.println("Main线程开始111");
try{
New.test(1);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("继续!!!!!!!!!!");
}
System.out.println("还没结束!!!!!!!");
}
我们看到,这几句打印其实是分开的,中间出现了一个异常
但是结果呢?
Main线程开始111
继续!!!!!!!!!!
还没结束!!!!!!!
java.lang.RuntimeException: aa
at com.fq.OnClass519.New.test(New.java:28)
at com.fq.OnClass519.New.main(New.java:10)
我们可以惊讶的发现,打印语句都放到了一起,异常最后抛出
为什么??????
其实异常捕获之后,创建对象的过程是在另外一个线程执行的,并不是在Main线程执行的
它先被捕获,但是等Main分配的时间到了以后,它再去异常的线程中创建对象,抛出异常