/**
* 1、异常: 程序执行过程中发生的不正常的情况
* 2、执行过程中发生的异常事件可分为两类:
* 1) Error: 错误,java虚拟机无法解决的严重问题。如:StackOverFlow(栈溢出)、OOM(Out Of Memory)
* error是严重错误,程序会崩溃
* 2) Exception: 可以预料的 程序运行时产生的错误,能够使用代码进行捕获处理,例如:空指针异常等
* Exception分为两类:运行时异常(程序运行时发生的异常)和编译时异常(编程时,由编译器检查出的异常)
* 3、运行时异常,编译器检查不出来。一般是指编程时的逻辑错误。java.lang.RuntimeException类及它的子类都是运行时异常类及它的子类都是运行时异常
* 4、编译时异常,是编译器要求必须处置的异常
* 5、Throwable 是所有异常类的父类,它实现了Serializable类同时继承Object类,
* 它的子类包含:Error 和 RuntimeException
* Error子类包含:StackOverFlow、OutOfMemory等子类
* RuntimeException子类包含:
* 1) NullPointException 空指针异常
* 2) ArithmeticException 数学运算异常
* 3) ArrayIndexOutOfBoundException 数组下标越界异常
* 4) ClassCastException 类型转换异常
* 5) NumberFormatException 数组格式异常
*
*
*/
**
* 1、异常处理:异常发生时,对异常的处理方式
* 2、俩种对异常的处理方式
* 1) try-catch-finally: 程序员在代码中捕获异常,自行处理
* 无论是否发生异常,finally 代码块总要执行,通常写释放资源的代码
* 2) throws:将发生的异常抛出,交给调用者处理,最顶级的调用者就是JVM
* 3、说明
* 1) t-c-f 和 throws 二选一即可
* 2) 若没有 t-c-f 异常捕获,默认throws抛出
* 3) JVM处理异常的方式:打印信息、终端程序
* 4、t-c-f语法
* try{
* // 认为会产生异常的代码
* }catch (异常){
* // 对捕获到的异常的处理
* }
* 说明:
* 1) 如果异常发生了,那么异常发生后面的代码不会执行,直接走 catch 语句块
* 2) 如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch
* 3) finally: 不管异常是否发生,都执行
* 4) 可以有多个catch语句块,捕获不同的异常。要求:父类异常在后,子类异常在前,如果发生异常,
* 只会匹配一个catch
* 5) try-finally: 这种用法相当于没有捕获异常,当异常发生时,finally执行完后,会直接崩掉
* 应用场景:执行一段代码,不管是否发生异常,都执行某段程序
* 6) t-c-f结构中,当 catch 语句块中有return语句时,会执行return的表达式,但不会马上返回,
* 会先执行finally语句块,优先返回finally语句块中的return,若finally中没有return,会返回catch中的return
/** 5、throws语法
* 1、介绍:如果一个方法可能生成某种异常,但是并不确定如何处理,则此方法应该显式的声明抛出异常
* 表明该方法将不对这些异常进行处理,而由该方法的调用者处理
* 2、在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常,
* 也可以是它的父类
* 3、说明:
* 1) 对于编译异常,程序中必须处理
* 2) 对于运行时异常,若程序中没有处理,默认throws抛出
* 3) 子类重写父类的方法,对抛出异常的规定:子类重写的方法,抛出异常的类型要么与父类一致,
* 要么为父类抛出异常的子类型
* 4、throw 和 throws 对比:
* 1) throw用于抛出某个具体的异常对象
* 2) throws抛出显式的异常声明,声明抛出的所有异常类型
*/
1、t-c-f 介绍
public class ExceptionHandle {
public static void main(String[] args) {
// 01
try {
String str = "jhfk";
int a = Integer.parseInt(str);
}catch (NumberFormatException e){
System.out.println("异常信息= "+e.getMessage());
}finally {
System.out.println("finally 代码块被执行...");
}
// 02
try {
Person jack = new Person("jack");
jack=null;
System.out.println(jack.getName()); // 会有一个异常
int n1 = 10;
int n2 = 0;
System.out.println(n1/n2); // 会有一个异常
}catch (NullPointerException e){
System.out.println("空指针异常");
}catch (ArithmeticException e){
System.out.println("算术异常");
}catch (Exception e){
System.out.println(e.getMessage());
}
System.out.println("程序继续...");
}
}
class Person{
private String name;
public String getName() {
return name;
}
public Person(String name) {
this.name = name;
}
}
2、t-c-f 练习
package level3.myEXception;
public class ExceptionExercise {
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.method());
}
}
class Test{
public int method(){
int i=1;
try {
i++; // i=2
String[] name = new String[3];
if(name[1].equals("tom")){ // 空指针异常-直接到catch语句块
System.out.println(name[1]);
}else{
name[3]="jack";
}
return 1;
}catch (ArrayIndexOutOfBoundsException e){
return 2;
}catch (NullPointerException e){
return ++i; // 执行 ++i,并赋值给临时变量tmp=3,不会立即返回,会先执行finally语句
// finally语句块中没有return,返回这里的tmp
}finally {
++i; // 执行++i,
System.out.println("i= " + i); // 输出 i=4
// return i; // 若这里有return,直接在这里返回,若没有,返回上级return的地方返回
}
}
}
3、throws
public class MyThrows {
public static void main(String[] args) {
// 调用方法时,选择处理f3方法抛出的运行时异常(不强制处理)
// 若不捕获,默认抛出
f3();
}
public static void f1(){
// 调用方法时,必须处理f2方法抛出的编译时异常(强制处理)
try {
f2();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void f2() throws FileNotFoundException {
// 抛出异常:FileNotFoundException - 编译时异常
FileInputStream fileInputStream = new FileInputStream("D://aa.txt");
}
public static void f3() throws ArithmeticException {
// 抛出异常:ArithmeticException - 运行时异常
int n1=10;
int n2=0;
double ret = n1/n2;
}
}
4、自定义异常
package level3.myEXception;
/**
* 1、当程序中出现的异常没有在 Throwable 子类中描述处理,此时可以自己设计异常类,用于描述该错误信息
* 2、
*
*/
public class MyDefindException {
public static void main(String[] args) {
int age=180;
// 要求范围在18-120之间,
if(!(age>=18 && age<=120)){
// 可以通过构造器,设置信息
throw new AgeException("年龄输入错误");
}
System.out.println("年龄范围正确");
}
}
// 自定义一个异常类型
// 1.继承 RuntimeException,如果直接继承Exception,调用时,会被认为是编译异常,必须处理
// 2.一般情况下,自定义异常继承 RuntimeException,好处是可以使用默认处理机制,比较方便
class AgeException extends RuntimeException{
// 定义构造器
public AgeException(String message){
super(message);
}
}