Java异常
目录
1、什么是异常
- 概念:程序在运行过程中出现的不正常现象。出现异常不处理将终止程序运行。
- 异常处理的必要性:任何程序都可能存在大量的未知问题、错误。如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。
- 异常处理:Java 编程语言使用异常处理机制为程序提供了异常处理的能力。
2、异常的分类
Throwable:可抛出的,一切错误或异常的父类,位于 java.lang 包中。
-
Error:JVM、硬件、执行逻辑错误,不能手动处理。
- StackOverflowError
- OutOfMemoryError
-
Exception:程序在运行和配置中产生的问题,可处理。
- RuntimeException:运行时异常,可处理,也可不处理。
- CheckedException:检查时异常,必须处理。
2.1、常见运行时异常

package com.liuxiang;
/**
* 演示常见运行时异常RuntimeException
* @author 86187
*/
public class Demo01 {
public static void main(String[] args) {
//1. NullPointerException
String name = null;
System.out.println(name.equals("zhangshan"));
//2. ArrayIndexOutOfBoundsException
int[] arr = {1,2,3};
System.out.println(arr[3]);
//3. ClassCastException
Object str1 = "123";
Integer integer = (Integer) str1;
//4. NumberFormatException
String str2 = "123a";
int i = Integer.parseInt(str2);
//5. ArithmeticException
int n = 10/0;
System.out.println(n);
}
}
Exception in thread "main" java.lang.NullPointerException
at com.liuxiang.Demo01.main(Demo01.java:12)
3、异常的产生和传递
异常的产生:当程序在运行时遇到不符合规范的代码或结果时,会产生异常或程序员使用 throw 关键字手动抛出异常。
异常的传递:按照方法的调用链反向传递,如始终没有处理异常,最终会由 JVM 进行默认异常处理(打印堆栈跟踪信息)并中断程序运行。
package com.liuxiang;
import java.util.Scanner;
/**
* 演示异常的产生和传递
* 要求:输入两个数字实现两个数字相除
* @author 86187
*/
public class Demo02 {
public static void main(String[] args) {
operation();
}
public static void operation(){
divide();
}
public static void divide(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入第一个数字");
int num1 = scanner.nextInt(); //如果出现异常没有处理,程序中断
System.out.println("请输入第二个数字");
int num2 = scanner.nextInt();
int result = num1/num2; //如果出现异常没有处理,所以程序中断
System.out.println(result);
System.out.println("程序执行完毕了...");
}
}
请输入第一个数字
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.liuxiang.Demo02.divide(Demo02.java:22)
at com.liuxiang.Demo02.operation(Demo02.java:16)
at com.liuxiang.Demo02.main(Demo02.java:12)
4、异常处理
Java 的异常处理是通过5个关键字来实现的:
- try:执行可能产生异常的代码
- catch:捕获异常,并处理
- finally:无论是否发生异常,代码总能执行
- throw:手动抛出异常
- throws:声明方法可能要抛出的各种异常
4.1、try...catch...

package com.liuxiang;
import java.util.Scanner;
/**
* 演示try...catch...语句使用
* (1)正常没有发生异常
* (2)发生异常并捕获
* (3)异常类型不匹配
* @author 86187
*/
public class Demo03 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int result = 0;
try {
System.out.println("请输入第一个数字");
int num1 = input.nextInt(); //InputMismatchException
System.out.println("请输入第二个数字");
int num2 = input.nextInt();
result = num1/num2; //ArithmeticException
} catch (Exception e) { //捕获Exception:是所有异常的父类
e.printStackTrace(); //打印堆栈跟踪信息
System.out.println(e.getMessage());
}
System.out.println("结果是:"+result);
System.out.println("程序结束了...");
}
}
请输入第一个数字
1
请输入第二个数字
0
java.lang.ArithmeticException: / by zero
at com.liuxiang.Demo03.main(Demo03.java:21)
/ by zero
结果是:0
程序结束了...
4.2、try...catch...finally

package com.liuxiang;
import java.util.Scanner;
/**
* 演示try...catch...finally...语句使用
* finally做后的:表示有没有异常都会执行的代码
* (1)正常没有发生异常
* (2)发生异常并捕获
* (3)异常类型不匹配
* @author 86187
*/
public class Demo04 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int result = 0;
try {
System.out.println("请输入第一个数字");
int num1 = input.nextInt(); //InputMismatchException
System.out.println("请输入第二个数字");
int num2 = input.nextInt();
result = num1/num2; //ArithmeticException
//System.exit(0); //手动退出JVM则不会执行finally
} catch (Exception e) { //捕获Exception:是所有异常的父类
e.printStackTrace(); //打印堆栈跟踪信息
System.out.println(e.getMessage());
}
finally {
System.out.println("释放资源");
}
System.out.println("结果是:"+result);
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.liuxiang.Demo04.main(Demo04.java:19)
null
释放资源
结果是:0
程序结束了...
4.3、多重catch

package com.liuxiang;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* 演示多重catch语句使用
* (1)正常没有发生异常
* (2)发生异常并捕获
* (3)异常类型不匹配
* @author 86187
*/
public class Demo05 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int result = 0;
try {
System.out.println("请输入第一个数字");
int num1 = input.nextInt(); //InputMismatchException
System.out.println("请输入第二个数字");
int num2 = input.nextInt();
result = num1/num2; //ArithmeticException
} catch (ArithmeticException e) {
System.out.println("算术异常");
}
catch (InputMismatchException e){
System.out.println("输入不匹配异常");
}
catch (Exception e){ //捕获Exception:是所有异常的父类
System.out.println("未知异常");
}
System.out.println("结果是:"+result);
System.out.println("程序结束了...");
}
}
请输入第一个数字
a
输入不匹配异常
结果是:0
程序结束了...
请输入第一个数字
10
请输入第二个数字
0
算术异常
结果是:0
程序结束了...
4.4、try...finally

package com.liuxiang;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* 演示多重try...finally...语句使用
* 不能处理异常,可以释放资源,把异常向上抛出
* @author 86187
*/
public class Demo06 {
public static void main(String[] args) {
try {
divide();
} catch (Exception e) {
System.out.println("出现异常:"+e.getMessage());
}
}
public static void divide(){
Scanner input = new Scanner(System.in);
int result = 0;
try {
System.out.println("请输入第一个数字");
int num1 = input.nextInt(); //InputMismatchException
System.out.println("请输入第二个数字");
int num2 = input.nextInt();
result = num1/num2; //ArithmeticException
}finally {
System.out.println("释放资源");
}
System.out.println("结果是:"+result);
System.out.println("程序结束了...");
}
}
请输入第一个数字
10
请输入第二个数字
0
释放资源
出现异常:/ by zero
5、声明异常
- 如果在一个方法体中抛出了异常,如何通知调用者?
- throws 关键字:声明异常
- 使用原则:底层代码向上声明或者抛出异常,最上层一定要处理异常,否则程序中断。
package com.liuxiang;
import java.util.Scanner;
/**
* throws:声明异常
* @author 86187
*/
public class Demo07 {
public static void main(String[] args) {
try {
divide();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void divide() throws Exception{
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数字");
int num1 = input.nextInt(); //InputMismatchException
System.out.println("请输入第二个数字");
int num2 = input.nextInt();
int result = num1/num2; //ArithmeticException
System.out.println("结果是:"+result);
System.out.println("程序结束了...");
}
}
请输入第一个数字
10
请输入第二个数字
0
/ by zero
6、抛出异常
- 除了系统自动抛出异常外,有些问题需要程序员自行抛出异常。
- throw 关键字:抛出异常
- 语法:throw 异常对象
package com.liuxiang;
public class Person {
private String name;
private String sex;
private int age;
public Person() {
}
public Person(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
if (sex.equals("男")||sex.equals("女")){
this.sex = sex;
}
else {
throw new RuntimeException("性别输入错误"); //运行时异常
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0&&age<=120){
this.age = age;
}
else {
//抛出异常
throw new RuntimeException("年龄不符合要求");
}
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
package com.liuxiang;
public class TestPerson {
public static void main(String[] args) {
Person person = new Person();
person.setSex("1");
person.setAge(200);
System.out.println(person.toString());
}
}
Exception in thread "main" java.lang.RuntimeException: 性别输入错误
at com.liuxiang.Person.setSex(Person.java:34)
at com.liuxiang.TestPerson.main(TestPerson.java:6)
7、自定义异常
- 需继承自 Exception 或 Exception 的子类,常用 RuntimeException。
- 必要提供的构造方法:
- 无参数构造方法
- String message 参数的构造方法
package com.liuxiang;
/**
* 自定义异常AgeException
* (1)继承Exception或其子类
* (2)添加构造方法
*/
public class AgeException extends RuntimeException{
public AgeException() {
}
public AgeException(String message) {
super(message);
}
public AgeException(String message, Throwable cause) {
super(message, cause);
}
public AgeException(Throwable cause) {
super(cause);
}
public AgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
package com.liuxiang;
public class Person {
private String name;
private String sex;
private int age;
public Person() {
}
public Person(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
if (sex.equals("男")||sex.equals("女")){
this.sex = sex;
}
else {
throw new RuntimeException("性别输入错误"); //运行时异常
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0&&age<=120){
this.age = age;
}
else {
//抛出异常
throw new AgeException("年龄不符合要求"); //自定义异常
}
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
package com.liuxiang;
public class TestPerson {
public static void main(String[] args) {
Person person = new Person();
person.setAge(200);
System.out.println(person.toString());
}
}
Exception in thread "main" com.liuxiang.AgeException: 年龄不符合要求
at com.liuxiang.Person.setAge(Person.java:48)
at com.liuxiang.TestPerson.main(TestPerson.java:6)

浙公网安备 33010602011771号