public static void main(String[] args) {
System.out.println("发生异常前");
int i = 1 / 0; //这里发生异常
System.out.println("发生异常后");
发生异常前
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.mine.demo01.Main1.main(Main1.java:6)
异常会打断程序的进行
什么是异常?
所以异常当然是指程序运行过程当中出现的问题,但是其本质,就是一个标识。
二、异常的结构和分类
1.Throwable:是所有异常和错误的共同父类
2.Error:错误是不可挽回的,不可修改的。(编译错误,类的缺失)
3.Exception:异常,是可以通过程序修正的。修正并不是把问题修改到没有,而是去进行策略上的弥补。
a.Exception:受查异常(要么捕获,要么抛出)
b.RuntimeException:运行时异常
三、异常的处理方式
1.异常的捕获
package com.mine.demo01;
public class Main1 {
public static void main(String[] args) {
System.out.println("发生异常前");
try {
int i = 1 / 0; //这里发生异常
}catch (ArithmeticException e){
e.printStackTrace();//打印异常的堆栈信息
System.out.println("发生异常后");
发生异常前
发生异常后
java.lang.ArithmeticException: / by zero
at com.mine.demo01.Main1.main(Main1.java:7)
结论:尽管异常发生了,但程序依然继续运行
(1)使用try,捕获某个区域当中,可能会发生的异常
(2)catch用于匹配异常
package com.mine.demo01;
public class Main1 {
public static void main(String[] args) {
System.out.println("发生异常前");
try {
int i = 1 / 0; //这里发生异常
}catch (NullPointerException e){
e.printStackTrace();//打印异常的堆栈信息
System.out.println("发生异常后");
发生异常前
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.mine.demo01.Main1.main(Main1.java:7)
如果异常不匹配,则try-catch不生效
(3)多catch匹配可以同时捕获多种异常
package com.mine.demo01;
public class Main1 {
public static void main(String[] args) {
System.out.println("发生异常前");
try {
int i = 1 / 0; //这里发生异常
}catch (NullPointerException e){
e.printStackTrace();//打印异常的堆栈信息
}catch (ArithmeticException e){
e.printStackTrace();//打印异常的堆栈信息
System.out.println("发生异常后");
发生异常前
发生异常后
java.lang.ArithmeticException: / by zero
at com.mine.demo01.Main1.main(Main1.java:7)
package com.mine.demo01;
public class Main1 {
public static void main(String[] args) {
System.out.println("发生异常前");
try {
String str = null;
str.length();//这里发生异常,终止try当中的运行,直接抵达catch
int i = 1 / 0;
}catch (NullPointerException e){
e.printStackTrace();//打印异常的堆栈信息
}catch (ArithmeticException e){
e.printStackTrace();//打印异常的堆栈信息
System.out.println("发生异常后");
发生异常前
发生异常后
java.lang.NullPointerException
at com.mine.demo01.Main1.main(Main1.java:8)
注意:在try当中,只要发生异常,try代码块中无论还有多少代码没执行,都将停止。抵达对应的异常catch,执行catch中的内容。
(4)在异常的catch列表当中,父类异常必须在后面
package com.mine.demo01;
public class Main1 {
public static void main(String[] args) {
System.out.println("发生异常前");
try {
String str = null;
str.length();//这里发生异常,终止try当中的运行,直接抵达catch
int i = 1 / 0;
}catch (NullPointerException e){
e.printStackTrace();//打印异常的堆栈信息
}catch (ArithmeticException e){
e.printStackTrace();//打印异常的堆栈信息
}catch (Exception e){
e.printStackTrace();
System.out.println("发生异常后");
(5)finally:无论如何都会被执行的代码块,即便return也无法阻止,想要阻止他,只能强制关闭虚拟机
package com.mine.demo01;
public class Main1 {
public static void main(String[] args) {
System.out.println("发生异常前");
try {
String str = null;
str.length();//这里发生异常,终止try当中的运行,直接抵达catch
int i = 1 / 0;
}catch (NullPointerException e){
e.printStackTrace();//打印异常的堆栈信息
}catch (ArithmeticException e){
e.printStackTrace();//打印异常的堆栈信息
}catch (Exception e){
e.printStackTrace();
}finally {
System.exit(1);//强制关闭虚拟机
System.out.println("无论如何都会执行");
System.out.println("发生异常后");
发生异常前
java.lang.NullPointerException
at com.mine.demo01.Main1.main(Main1.java:8)
一些应用场景:比如关闭连接,关闭流,等等。
2.自动抛出异常
checked异常通常可以考虑抛出
处理异常的策略:谁调用谁处理
C.java
package com.mine.demo01;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class C {
public void fun() throws ParseException,Exception{
SimpleDateFormat sdf = new SimpleDateFormat("");
sdf.parse("");
B.java
package com.mine.demo01;
public class B {
C c = new C();
public void fun() throws Exception{
c.fun();
A.java
package com.mine.demo01;
public class A {
B b = new B();
public void fun() throws Exception{
b.fun();
Main.java
package com.mine.demo01;
public class Main2 {
public static void main(String[] args) {
A a = new A();
try { //捕获异常为最终处理异常的方式
a.fun();
}catch (Exception e){
throw new RuntimeException(e);
异常的堆栈信息
Exception in thread "main" java.lang.RuntimeException: java.text.ParseException: Unparseable date: ""
at com.mine.demo01.Main2.main(Main2.java:9)
Caused by: java.text.ParseException: Unparseable date: ""
at java.text.DateFormat.parse(DateFormat.java:366)
at com.mine.demo01.C.fun(C.java:9)
at com.mine.demo01.B.fun(B.java:6)
at com.mine.demo01.A.fun(A.java:6)
at com.mine.demo01.Main2.main(Main2.java:7)
打印堆栈信息:e.printStackTrace();
最下面的是最开始的调用方法,最上面的是最开始出现异常的地方。
异常的信息包含:
1.异常的内容
2.异常的类型
3.异常所发生的类
4.异常所发生的方法
5.异常发生的位置,即行数
3.手动抛出异常
由开发者自己定义的异常行为
Person.java
package com.mine.demo02;
public class Person {
private Integer age;
public Integer getAge(){
return age;
public void setAge(Integer age){
if(age < 0 || age > 120){
throw new RuntimeException("年龄不符合,您确定您是人类吗?");
this.age = age;
Main.java
package com.mine.demo02;
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setAge(250);
Exception in thread "main" java.lang.RuntimeException: 年龄不符合,您确定您是人类吗?
at com.mine.demo02.Person.setAge(Person.java:12)
at com.mine.demo02.Main.main(Main.java:6)
4.自定义异常
自定义异常的创建方式
1.继承Exception或者RuntimeException
2.名字通常是XxxException
3.对父类构造进行调用
AgeBoundException.java
package com.mine.demo02;
public class AgeBoundException extends RuntimeException{
private Integer age;
public AgeBoundException(){
super();
public AgeBoundException(String message){
super(message);
public AgeBoundException(Throwable cause){
super(cause);
public AgeBoundException(String message,Throwable cause){
super(message,cause);
protected AgeBoundException(String message,Throwable cause,Boolean enableSuppression,boolean writableStackTrace){
super(message, cause,enableSuppression,writableStackTrace);
public void setAge(Integer age){
if(age < 0 || age > 120){
throw new RuntimeException("年龄不符合,您确定您是人类吗?");
this.age = age;
Main.java
package com.mine.demo02;
public class Main1 {
public static void main(String[] args) {
AgeBoundException ageBoundException = new AgeBoundException();
ageBoundException.setAge(250);
Exception in thread "main" java.lang.RuntimeException: 年龄不符合,您确定您是人类吗?
at com.mine.demo02.AgeBoundException.setAge(AgeBoundException.java:24)
at com.mine.demo02.Main1.main(Main1.java:6)