1.throw
关键字
- 必须写在方法的内部
-
throw
后面new
的对象只能是Exception
或者其子类 -
throw
抛出的指定异常对象,我们必须处理: throw
后面new
的对象如果是RuntimeException
或者其子类,运行期异常,可以不管,默认交给JVM处理(打印异常,中断程序)throw
后面new
的对象如果是Exception
,或者其某些子类,编译期异常(写代码的时候报错),要么throws
,要么try...catch
以后在工作中,必须对方法参数进行合法性校验,如果参数不合法,必须使用抛出异常
例子:
编写一个方法,要求实现打印数组在索引出的元素
普通写法:
public class Demo02 {
public static void main(String[] args) {
}
public static void method(int[] array,int index){
System.out.println(array[index]);
}
}
正常情况下我们会要求:数组不能为null,指针不能超过数组长度
public class Demo02 {
public static void main(String[] args) {
}
public static void method(int[] array,int index){
if (array==null){
throw new NullPointerException("传递的数组为空");
}
if (index<0 || index>array.length-1){
throw new ArrayIndexOutOfBoundsException("索引越界");
}
System.out.println(array[index]);
}
}
2.Objects.requireNonNull()
非空判断
import java.util.Objects;
public class Demo03 {
public static void main(String[] args) {
int[] array = null;
Objects.requireNonNull(array);
}
}
import java.util.Objects;
public class Demo03 {
public static void main(String[] args) {
int[] array = null;
Objects.requireNonNull(array,"数据为null");
}
}
3.throws
声明异常
- 格式:
public static void method(参数) throws AAAException,BBBException,CCCException{
throw new AAAException("产生原因");
throw new BBBException("产生原因");
throw new CCCException("产生原因");
方法体;
}
- 注意:
throws
关键字声明的异常必须是Exception
异常或者其子类;- 调用一个声明了异常的方法,就必须处理该异常,要么
throws
,要么try...catch
import java.io.FileNotFoundException;
public class Demo04 {
public static void main(String[] args) {
}
public static void method(String way) throws FileNotFoundException {
if (!way.equals("c://a.txt")){
throw new FileNotFoundException("文件找不到");
}
}
}
- 调用一个声明了异常的方法,就必须处理该异常,要么
throws
,要么try...catch
import java.io.FileNotFoundException;
public class Demo04 {
public static void main(String[] args) throws FileNotFoundException {//调用一个声明了异常的方法,就必须处理该异常,要么`throws`,要么`try...catch`
method("c://e.txt");
}
public static void method(String way) throws FileNotFoundException {
if (!way.equals("c://a.txt")){
throw new FileNotFoundException("文件找不到");//FileNotFoundException()为编译异常,要么`throws`,要么`try...catch`
}
}
}
4.try...catch
捕捉异常
- 快捷键:
Alt+回车 - 格式:
try {
可能产生异常的语句;
}catch (异常变量,用于接收try抛出的异常){
处理异常的逻辑;(一般会把异常信息记录到日志中)
}catch(异常变量){
处理异常的逻辑;
}catch(异常变量){
处理异常的逻辑;
}
可以使用多个catch
来处理try
抛出的多个异常
import java.io.FileNotFoundException;
public class Demo05 {
public static void main(String[] args) {
try {
method("c://b.txt");
}catch (FileNotFoundException f){
System.out.println("不是a.txt文件");
}
System.out.println("后续代码");
}
public static void method(String file) throws FileNotFoundException {
if (!file.equals("c://a.txt")){
throw new FileNotFoundException();
}
}
}
-
try...catch
中常用的三种显示错误的方法 getMessage()
显示异常描述toString()
显示异常类型和信息printStackTrace
打印跟踪栈信息输出到控制台
import java.io.FileNotFoundException;
public class Demo05 {
public static void main(String[] args) {
try {
method("c://b.tx");
}catch (FileNotFoundException f){
System.out.println(f.getMessage());
System.out.println(f.toString());
f.printStackTrace();
}
}
public static void method(String file) throws FileNotFoundException {
if (!file.equals("c://a.txt")){
throw new FileNotFoundException("文件不对");
}
}
}
5.finally
try {
可能产生异常的语句;
}catch(异常变量){
处理异常的逻辑;
}finally{
无论是否发生异常,都会执行;
}
- 注意:
- 不能单独使用,只能与
try
连用 - 一般用于资源释放
- 如果
finally{}
中有return
那么会永远返回finally
中的结果,应该避免
import java.io.FileNotFoundException;
public class Demo05 {
public static void main(String[] args) {
try {
method("c:d.tex");
} catch (FileNotFoundException e) {
System.out.println(e.toString());
}finally {
System.out.println("测试执行");
}
}
public static void method(String file) throws FileNotFoundException {
if (!file.equals("c://a.txt")){
throw new FileNotFoundException("文件不对");
}
}
}
6.多个异常处理
- 多个异常分别处理
import java.util.List;
public class Demo06 {
public static void main(String[] args) {
try {
int[] array = {1, 2, 3};
System.out.println(array[3]);
} catch (ArrayIndexOutOfBoundsException a1) {
System.out.println(a1.toString());
}
try {
List<Integer> list = List.of(1, 2, 3);
list.get(3);
} catch (ArrayIndexOutOfBoundsException a2) {
System.out.println(a2.toString());
}
}
}
- 多个异常,一次捕获,分别处理
import java.util.List;
import java.util.Objects;
public class Demo07 {
public static void main(String[] args) {
try {
int[] array = {1, 2, 3};
System.out.println(array[3]);
Objects obj = null;
obj.equals("123");
} catch (ArrayIndexOutOfBoundsException a1) {
System.out.println(a1.toString());
} catch (NullPointerException a2) {
System.out.println(a2.toString());
}
System.out.println("后续代码");
}
}
首先发现第一个异常
第一个异常改进后会检查第二个异常
import java.util.List;
import java.util.Objects;
public class Demo07 {
public static void main(String[] args) {
try {
int[] array = {1, 2, 3};
System.out.println(array[1]);
Objects obj = null;
obj.equals("123");
} catch (ArrayIndexOutOfBoundsException a1) {
System.out.println(a1.toString());
} catch (NullPointerException a2) {
System.out.println(a2.toString());
}
System.out.println("后续代码");
}
}
注意:多个catch
里的异常变量如果有父级与子级的关系,子类必须先catch
- 一次捕获,一次处理
catch(Exception a){
}
import java.util.List;
import java.util.Objects;
public class Demo07 {
public static void main(String[] args) {
try {
int[] array = {1, 2, 3};
System.out.println(array[3]);
Objects obj = null;
obj.equals("123");
} catch (Exception a1) {
System.out.println(a1.toString());
}
System.out.println("后续代码");
}
}
首先发现第一个异常
第一个异常改进后会检查第二个异常
import java.util.List;
import java.util.Objects;
public class Demo07 {
public static void main(String[] args) {
try {
int[] array = {1, 2, 3};
System.out.println(array[1]);
Objects obj = null;
obj.equals("123");
} catch (Exception a1) {
System.out.println(a1.toString());
}
System.out.println("后续代码");
}
}
7.自定义异常类
public class XXXException extends Exception{ //编译期异常
添加一个无参构造;
添加一个带异常信息的构造方法;
}
public class XXXException extends RuntimeException{//运行期期异常
添加一个无参构造;
添加一个带异常信息的构造方法;
}
public class DemoException extends Exception {
public DemoException() { 空参构造
}
public DemoException(String message) { 带参构造
super(message); 继承父类信息
}
}
练习
public class DemoException extends Exception {
public DemoException() {
}
public DemoException(String message) {
super(message);
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class DemoPractice {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Scanner in = new Scanner(System.in);
System.out.print("请输入用户名:");
String name = in.next();
try {
againName(names, name);
} catch (DemoException a) {
System.out.println(a.toString());
}
names.add(name);
}
}
public static void againName(List list, String name) throws DemoException {
if (list.contains(name)) {
throw new DemoException("已经包含该用户");
}
}
}