13.异常处理
1. 异常
我们的程序会意外终止。统一都叫异常。
Throwable有两个子类: Error 和 Exception
Error: 一般是系统级的。我们控制不了,和我们无关!
Exception: 异常: 需要我们控制的
public static void main(String[] args) {
abc();
System.out.println(10 / 1);
System.out.println(10 / 0.0);
Person p = new Person("乾隆");
Person p1 = new Person("嘉庆", p);
Throwable t1 = new Throwable("A原因蝴蝶闪了一下翅膀");
Throwable t2 = new Throwable("B原因台风", t1);
// Throwable t3 = t2.fillInStackTrace();
// System.out.println(t3);
Throwable t4 = t2.getCause();
System.out.println(t4);
System.out.println(t1 == t4);
System.out.println(t2.getMessage());
StackTraceElement[] se = t2.getStackTrace();
for (StackTraceElement item: se) {
System.out.println(item);
}
t2.printStackTrace();
// ArithmeticException ae = new ArithmeticException();
// ae.printStackTrace();
}
private static void abc() {
// TODO Auto-generated method stub
System.out.println(10 / 0);
}
Throwable; 顶层类:
Throw
- message属性: 错误信息 getMessage();
- cause: 导致这个错误的错误
- printStackTrace(): 打印错误栈中的信息
2. 异常: Exception
- RuntimeException: 运行时异常:就是你写错了! 不需要手动处理!
- CheckedException: 这个类不存在。除了RuntimeException其他都是检查异常,编译异常。需要手动处理
public static void main(String[] args) throws ParseException {
// StackOverflowError
System.out.println(10 / 0); // 运行时异常
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse("2021-2-aa"); // 编译时异常
}
3. RuntimeException
五个常用:
异常名 | 意义 | 意义 |
---|---|---|
ArithmeticException | 算术异常 | System.out.println(10 / 0); // 运行时异常 |
NullPointerException | 空指针异常 | obj = null; obj.*** 对象为空 if ("".equals(a2)) { |
IndexOutOfBoundsException | 下标越界 | 下标越界 ArrayIndexOutOfBoundsException数组下标越界 |
ClassCastException | 类型转换异常 | A a = new C(); B b = (B) a; |
IllegalArgumentException | 严重的参数异常 | JDK提供的方法。参数不正确 |
4. throw与throws关键字:
-
throw + 异常对象: 相当于return:方法就结束了。
-
throws :修饰方法。 一般用于checkedException::: 可以抛出多个异常
※ throws checkedException的时候,谁调用谁倒霉
public static void main(String[] args) throws Throwable {
int r = add(1, 0x7FFFFFFF);
System.out.println(r);
}
private static int add(int i, int j) throws ArithmeticException, IOException, Throwable {
if (Integer.MAX_VALUE - i < j) {
throw new ArithmeticException("超过范围");
}
return i + j;
}
5. 异常的处理:
第一种throws方式:往上抛
第二种:异常的捕获:
try{… } catch(**Exception e) {…} finally {… }
try {
要捕获异常的代码
} catch(XXException e) {
异常时的处理代码
} catch(XXException e) {
..
} finally {
不管是否异常都会运行的代码 // 场景: IO的关闭
}
try {
要捕获异常的代码
} catch(XXException|XXException|。。 e) {
异常时的处理代码
} finally {
不管是否异常都会运行的代码 // 场景: IO的关闭
}
try (可以关闭的变量的定义) {
} catch (Exception x) {
}
catch()catch(): 父子不能乱, 同级随便
catch(多个): 多个可以时并列, 不能是父子
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
try {
sdf.parse("2021");
System.out.println("-=end==");
return;
// System.exit(1); // 中断程序
} catch (ParseException e) {
e.printStackTrace(); // 多线程打印
} finally {
System.out.println("---finally--");
}
public static void main(String[] args) {
try {
// 父子不能乱, 同级随便
abc();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// catch(多个): 多个可以时并列, 不能是父子
abc();
} catch (FileNotFoundException|ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void abc() throws FileNotFoundException, IOException, ParseException, Exception {
}
6. 自定义异常
一般继承自Exception; 是CheckedException. 生成Exception中的构造方法。
package com.etc.lesson13;
import java.text.MessageFormat;
import lombok.Data;
public class TestMain8 {
public static void main(String[] args) {
try {
System.out.println(add(1, 0x7FFFFFFF));
} catch (MyMathException2 e) {
// e.printStackTrace();
System.out.println(e.getMessage());
Object o = e.getData(); // 额外的返回数据
String[] strsdata = (String[]) o;
for (String item: strsdata) {
System.out.println(item);
}
System.out.println(MessageFormat.format(e.getMessage(), strsdata));
}
System.out.println("================");
}
public static int add(int i, int j) throws MyMathException2 {
if (Integer.MAX_VALUE - i < j) {
// throw new MyMathException("超过范围");
// throw new MyMathException2("超过范围");
MyMathException2 e = new MyMathException2("{0}-{1}-{2}的错误!");
e.setData(new String[]{"a", "b", "c"});
throw e;
}
return i + j;
}
}
class MyMathException extends ArithmeticException {
public MyMathException() {
super();
// TODO Auto-generated constructor stub
}
public MyMathException(String s) {
super(s);
// TODO Auto-generated constructor stub
}
}
@Data
class MyMathException2 extends Exception {
private Object data;
public MyMathException2() {
super();
// TODO Auto-generated constructor stub
}
public MyMathException2(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public MyMathException2(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public MyMathException2(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public MyMathException2(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
(message, cause);
// TODO Auto-generated constructor stub
}
public MyMathException2(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public MyMathException2(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}