异常(Exception)是程序执行过程中所产生的问题
产生原因:用户输入无效数字、找不到需要打开的文件、在通讯中网络连接中断、JVM发生了内存溢出
异常的三个种类:检查异常、运行时异常、错误(类似异常、无法控制)
异常(Exception)处理:捕获异常不让它沿着调用栈继续向下抛出、
捕获并继续向下抛出、
不捕获导致方法从调用栈中弹出异常对象继续抛给调用栈的main()方法。
Throwable 类是 Java 语言中所有错误(Error)或异常(Exception)的超类(这就是一切皆可抛的东西)。
它有两个子类:Error和Exception。
① RuntimeException和 IOException等继承Exception,具体的RuntimeException继承RuntimeException。
② Error和RuntimeException及其子类成为运行时异常(unchecked)。其他的称为检查异常(checked)。
粉红色的是受检查的异常(checked exceptions),其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明.受检查的异常必须在编译时被捕捉处理,命名为 CHecked Exception 是因为Java编译器要进行检查,Java虚拟机也要进行检查,以确保这个规则得到遵守.
绿色的异常是运行时异常(runtime exceptions),需要程序员自己分析代码决定是否捕获和处理,比如 空指针,被0除...
而声明为Error的,则属于严重错误,需要根据业务信息进行特殊处理,Error不需要捕捉。
非RuntimeException(checkedException)和RuntimeException(uncheckedException)区别
① RuntimeException:RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。 也可以主动抛出异常,停止程序运行。if(obj==null){throw new exception};......
②其他非RuntimeException(IOException等等):这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。
1. checkedException 在程序中必须使用try...catch进行处理。
比如一个IO系统的设计者会认为诸如物理文件不存在或者介质无法读取等异常时很可能 发生,而使用者完全可能捕获这个异常,通过让用户 重新输入文件名等方式重新进行这个操作,也就是说,这是一个可恢复的操作。所以我会在诸如 read()/write()等操作中throw 一个 IOException(checked exception)。同时还要在Finally中关闭连接,数据库连接同理。(记得File 如果没有找到,然后file.close()会抛异常,所以要先判断file是否为null)
2. RuntimeException可以不使用try...catch进行处理但是如果有异常产生则异常将由JVM进行处理。
对于RuntimeException的子类最好也使用异常处理机制。虽然 RuntimeException的异常可以不使用try...catch进行处理但是如果一旦发生异常则肯定会导致程序中断执行所以为了保证程 序再出错后依然可以执行在开发代码时最好使用try...catch的异常处理机制进行处理
RuntimeException也可以说是程序员的错误,程序员可以通过优秀的代码编写,来避免runtimeException.
运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。而Exception是指出现错误后,可以由程序员进行补救或其他工作。
异常处理:
1.简单的处理异常,直接printstack 印栈跟踪信息
4.在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。
2.不指定具体的异常
3.保证所有资源都被正确释放。充分运用finally关键词。
5.过于庞大的try块
6.输出数据不完整(只要有数据输出或者写文件,一定要特别考虑异常发生会导致的结果)
try{}catch语句块:
try{
//被保护的语句块
}catch(异常声明(ex:FileNotFoundException f){
//捕获块 ex:直接printstack 印栈跟踪信息的语句为:f.printstack();
}
一个try{}catch并不能捕获一切所以可有多个catch语句。
因多态的原因(父子类关系):Catch块不能随意列出,所以将Catch声明的时异常中子类写在前面
Finally语句:出现在try{}catch的最后,总是会被执行(ex:清理类型的语句)
注:异常处理和声明规则不适用于运行时异常。
声明异常:
若一个方法未处理检查异常那么该方法就必须使用Throws关键字来声明异常,放在方法签名末尾
ex:声明抛出一个RemoteException异常(public void deposit(double amount)Throws RemoteException){});
若要声明多个,异常间用“,”隔开即可。
抛出异常:
Throw:抛出异常,导致当前代码立即停止执行异常将抛给调用栈的前一个方法。
Throw new Exception or RuntimeException();
抛出检查异常时需用Throws在方法签名处声明。
自定义异常:
所有异常必须是Throwable 的子类
编写检查异常时需继承Exception 类
编写运行时类需继承RuntimeException类
注:自定义异常通常是定义一个继承自Exception类的子类。
一般情况下我们都会直接继承自Exception类,而不会继承某个运行时的异常类。
import java.util.Scanner;
public class Exception1 {
//输入字符串判断
public static void main(String[] args) {
Scanner input= new Scanner(System.in); //输入声明
System.out.println("输入数字字符串");
String StringOne=input.next(); //第一个
String StringTwo=input.next(); //第二个
try{
//类型转换
Integer.parseInt(StringOne);
Integer.parseInt(StringTwo);
} catch(ArrayIndexOutOfBoundsException a){
System.out.println("您未输入");//提示未输入
a.printStackTrace();
/*未输入时: String StringOne=null;
String StringTwo=null;
输入数字字符串
请输入整型数据
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:454)
at java.lang.Integer.parseInt(Integer.java:527)
at exception1.Exception1.main(Exception1.java:13)*/
return ;
}catch(NumberFormatException n){
System.out.println("请输入整型数据");
/*输入不为整型时:
输入数字字符串
234e
3333d
请输入整型数据
java.lang.NumberFormatException: For input string: "234e"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at exception1.Exception1.main(Exception1.java:13)*/
n.printStackTrace();
} catch(RuntimeException r){
System.out.println("发生错误");//运行时错误
r.printStackTrace();}
System.out.println("IntOne:"+Integer.parseInt(StringOne)+",IntTwo:"+Integer.parseInt(StringTwo)
+"\n两数乘积为:"+(Integer.parseInt(StringOne)*Integer.parseInt(StringTwo)));
}
}
补充:Thread.sleep(5000); //休眠5秒