14.异常
异常
概述
异常: 程序出现的不正常情况
异常体系:
- Error: 严重问题, 不需要处理
- Exception: 称为异常类, 表示程序本身可以处理的问题
- RuntimeException: 在编译期不检查的异常, 出问题后, 需要修改代码
- 非RuntimeException: 编译期就必须处理掉的, 否则程序不能通过编译, 就更不能正常运行了
JVM默认处理方法
如果程序出了问题,代码没有做处理, JVM会默认处理
- 输出异常的名称, 异常原因及异常出现的位置信息在控制台
- 程序停止执行
demo
package exception;
public class DefaultDeal {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
public static void method() {
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
}
/*
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at exception.DefaultDeal.method(DefaultDeal.java:12)
at exception.DefaultDeal.main(DefaultDeal.java:6)
*/
}
异常处理
格式
try {
可以出现异常的代码;
} catch (异常名 变量名) {
异常处理代码;
}
Demo
package exception;
public class TryCatch {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
public static void method() {
try {
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {
// System.out.println("数组索引越界");
e.printStackTrace();
}
}
}
Throwable成员方法
方法名 | 说明 |
---|---|
public String getMessage() | 返回此 throwable的详细消息字符串 |
public String toString() | 返回此可抛出的简短描述 |
public void printStackTrace() | 把异常的错误信息输出在控制台 |
demo
package exception;
public class ThrowableDemo {
public static void main(String[] args) {
System.out.println("start");
method();
System.out.println("end");
}
public static void method() {
try {
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {
// e.printStackTrace();
System.out.println(e.getMessage()); // Index 3 out of bounds for length 3
System.out.println(e.toString()); // java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
}
}
编译时异常和运行异常
java异常类分为两大类: 编译时异常和运行时异常, 也被称为受检异常和非受检异常
所有RuntimeException类及其子类称为运行时异常, 其他的异常都是编译时异常
- 编译时异常: 必须显示处理, 否则程序就会发生错误, 无法通过编译
- 运行时异常: 无需显示处理, 也可以和编译是异常一样处理
Demo
package exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CompileRuntimeException {
public static void main(String[] args) {
System.out.println("start");
method();
method2();
System.out.println("end");
}
// 运行时异常: 运行时程序逻辑处理抛出的问题
public static void method() {
int [] arr = {1, 2, 3};
System.out.println(arr[3]);
}
// 编译时异常: 编译过程中程序判断可能出问题
public static void method2() {
try {
String s = "2020-08-09";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(s);
System.out.println(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
throws处理异常
针对一些没有权限进行异常的处理, java提供了throws处理方法
格式
throws 异常类名;
注意: 格式跟在方法括号后面
- 编译时异常必须进行处理: 两种处理方法: try...catch...或者throws, 如果采取throws方案, 将来谁调用谁处理
- 运行时异常可以不处理: 出问题后需要回来修改代码
demo
package exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ThrowsDemo {
public static void main(String[] args) {
System.out.println("start");
// method();
try {
method2();
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("end");
}
// 运行时异常: 运行时程序逻辑处理抛出的问题
/*
public static void method() throws ArrayIndexOutOfBoundsException {
int [] arr = {1, 2, 3};
System.out.println(arr[3]);
}
*/
// 编译时异常: 编译过程中程序判断可能出问题
public static void method2() throws ParseException {
String s = "2020-08-09";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(s);
System.out.println(d);
}
}
自定义异常 throw
格式
public class 异常类名 extends Exception {
无参构造
带参构造
}
范例
public class ScoreException extends Exception {
public ScoreException() {}
public ScoreException(String message) {
super(message);
}
}
示例
ScoreException
package exception.customException;
public class ScoreException extends Exception {
public ScoreException() {}
public ScoreException(String message) {
super(message);
}
}
Teacher
package exception.customException;
public class Teacher {
public void checkSrore(int score) throws ScoreException {
if(score<0 || score>100) {
// throw new ScoreException();
throw new ScoreException("分数有误, 范围应该在0~100");
} else {
System.out.println("正常分数");
}
}
}
Demo
package exception.customException;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入分数;");
int score = sc.nextInt();
Teacher t = new Teacher();
try {
t.checkSrore(score);
} catch (ScoreException e) {
e.printStackTrace();
}
}
}
throws和throw区别
throws
- 用在方法声明后面, 跟的是异常类名
- 表示抛出异常, 由该方法的调用者来处理
- 表示出现异常的一种可能性, 并不一定会发成这些异常
throw
-
用在方法体内, 跟的是异常对象名
-
表示抛出异常,有方法体内的语句处理
-
指定throw一定抛出了某种异常
衣带渐宽终不悔,为伊消得人憔悴!