java if 异常_Java 异常的处理

throw关键字

作用

可以使用throw关键字在指定的方法中抛出指定的异常

使用格式

throw new xxxException(“异常产生的原因“)

注意

throw关键字必须写在方法的内部

throw关键字后边new的对象必须是 Exception或者 Exception的子类对象

throw关键字抛出指定的异常对象,我们就必须处理这个异常对象。

throw关键字后边创建的是 RuntimeException或者是RuntimeException的子类对象,我们可以不处理,默认交给JW处理(打印异常对象,中断程序)

throw关键字后边创建的是编译异常,我们就必须处理这个异常,要么 throws,要么try...catch

举例

例子1:

public classDemoThrow {public static voidmain(String[] args) {int[] array ={};int element = DemoThrow.getElement(array, 1);

}public static int getElement(int[] array, intindex) {if (array.length == 0) {throw new NullPointerException("传入的数组为空");

}else if (index == 0 || index > array.length - 1) {throw new ArrayIndexOutOfBoundsException("传递的索引超出了数组的适用范围");

}else{returnarray[index];

}

}

}

抛出错误:

Exception in thread"main" java.lang.NullPointerException: 传入的数组为空

at XXX.DemoThrow.getElement(DemoThrow.java:10)

at XXX.DemoThrow.main(DemoThrow.java:5)

例子2:

public classDemoThrow {public static voidmain(String[] args) {int[] array = {1, 2, 3};int element = DemoThrow.getElement(array, 100);

}public static int getElement(int[] array, intindex) {if (array.length == 0) {throw new NullPointerException("传入的数组为空");

}else if (index == 0 || index > array.length - 1) {throw new ArrayIndexOutOfBoundsException("传递的索引超出了数组的适用范围");

}else{returnarray[index];

}

}

}

抛出错误:

Exception in thread"main" java.lang.ArrayIndexOutOfBoundsException: 传递的索引超出了数组的适用范围

at XXX.DemoThrow.getElement(DemoThrow.java:12)

at XXX.DemoThrow.main(DemoThrow.java:5)

Objects非空判断requireNonNull

java.util.Objects类是由一些静态实用方法组成,这些方法是空指针安全的(即:容忍空指针的)

在源码中对对象null值进行了抛出异常错误

源码如下://查看指定对象时不时null

public static T requireNonNull(T obj) {if (obj == null)throw newNullPointerException();returnobj;

}

requireNonNull方法的使用

importjava.util.Objects;public classDemoObjectsNonNull {public static voidmain(String[] args) {

String s= null;

Objects.requireNonNull(s,"传入的参数为空");

}

}

抛出错误:

Exception in thread"main" java.lang.NullPointerException: 传入的参数为空

at java.util.Objects.requireNonNull(Objects.java:228)

at XXX.DemoObjectsNonNull.main(DemoObjectsNonNull.java:6)

自定义非空判断

public classDemoObjectsNonNull {public static voidmain(String[] args) {

String s= null;

methodNonNull(s);

}public static voidmethodNonNull(E e) {if (e == null) {throw new NullPointerException("传入的参数为空");

}

}

}

抛出错误:

Exception in thread"main" java.lang.NullPointerException: 传入的参数为空

at XXX.DemoObjectsNonNull.methodNonNull(DemoObjectsNonNull.java:9)

at XXX.DemoObjectsNonNull.main(DemoObjectsNonNull.java:5)

异常处理的第一种方式:throws

throws作用

当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象。可以使用 throws关键字处理异常对象,它会把异常对象声明抛给方法的调用者处理(自己不处理,绐别人处理)最终交给JVM-->中断处理

使用格式

修饰符 返回值类型 方法名(参数列表)throwsAaaException, BbbException ... {throw new AaaException("产生原因");throw new BbbException("产生原因");

...

}

注意

throws关键字必须写在方法声明处。

throws关键字后边声明的异常必须是Exception或者是Exception的子类。

方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常。如果批出的多个异常对象有子父类关系,那么直接声明父类异常即可

调用了一个声明抛出异常的方法,我们就必须处理声明的异常,要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM,要么try...catch自己处理异常。

举例

例子1:

importjava.io.FileNotFoundException;public classDemo01Throws {public static void main(String[] args) throwsFileNotFoundException{

String s= "/Users/data.txt";

readFile(s);

}public static void readFile(String s) throwsFileNotFoundException {if ("/Users/data.txt".equals(s)) {

System.out.println("传入的参数是'/Users/data.txt'");

}else{throw new FileNotFoundException("传入的参数不是'/Users/data.txt'");

}

}

}

输出结果:

传入的参数是'/Users/data.txt'

例子2:

importjava.io.FileNotFoundException;public classDemo01Throws {public static void main(String[] args) throwsFileNotFoundException{

String s= "/Users/data";

readFile(s);

}public static void readFile(String s) throwsFileNotFoundException {if ("/Users/data.txt".equals(s)) {

System.out.println("传入的参数是'/Users/data.txt'");

}else{throw new FileNotFoundException("传入的参数不是'/Users/data.txt'");

}

}

}

抛出错误:

Exception in thread"main" java.io.FileNotFoundException: 传入的参数不是'/Users/data.txt'

at XXX.Demo01Throws.readFile(Demo01Throws.java:11)

at XXX.Demo01Throws.main(Demo01Throws.java:6)

异常处理的第二种方式:try catch

使用格式

格式:try{

...

}catch(异常类名 变量名) {

...

}

...catch(异常类名 变量名) {

...

} ...

注意

try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象。

如果try中产生了异常,那么就会执行ctch中的异常处理逻辑,执行完catch中的处理逻辑,会继续执行try...catch之后的代码。

如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try...catch之后的代码。

举例

public classDemo01TryCatch {public static voidmain(String[] args) {try{

String[] strings={};

System.out.println(strings[100]);

}catch(ArrayIndexOutOfBoundsException e) {//数组索引越界异常

System.out.println("Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException");

}catch(NullPointerException e) {//空指针异常

System.out.println("Exception in thread \"main\" java.lang.NullPointerException");

}

System.out.println("程序执行完成");

}

}

输出结果:

Exception in thread"main"java.lang.ArrayIndexOutOfBoundsException

程序执行完成

Throwable类中3个异常处理的方法

public voidprintStackTrace():打印异常的跟踪栈信息,并输出到控制台。包含了异常的类型,异常的原因,还包括异常出现的位置。在开发和调试阶段都得使用printStackTrace。publicString getMessage():获取发生异常的原因。提示给用户时候就提示误原因。public String toString():获取异常的类型和异常描述信息。

printStackTrace()方法源码

public voidprintStackTrace() {

printStackTrace(System.err);

}

getMessage()方法源码

publicString getMessage() {returndetailMessage;

}

toString()方法源码

publicString toString() {

String s=getClass().getName();

String message=getLocalizedMessage();return (message != null) ? (s + ": " +message) : s;

}

三个方法举例

public classDemoTryCatch {public static voidmain(String[] args) {try{

String[] strings= new String[10];

getElement(strings,10);

}catch(ArrayIndexOutOfBoundsException e) {//获取发生异常的原因

System.out.println(e.getMessage());//获取异常的类型和异常描述信息

System.out.println(e.toString());//获取栈的跟踪信息(异常的类型、异常的原因、异常出现的位置)

e.printStackTrace();

}

}public static String getElement(String[] array, intindex) {if (array.length == 0) {throw new NullPointerException("传入的数组为空");

}else if (index == 0 || index > array.length - 1) {throw new ArrayIndexOutOfBoundsException("传递的索引超出了数组的适用范围");

}else{returnarray[index];

}

}

}

控制台输出:

传递的索引超出了数组的适用范围

java.lang.ArrayIndexOutOfBoundsException: 传递的索引超出了数组的适用范围

java.lang.ArrayIndexOutOfBoundsException: 传递的索引超出了数组的适用范围

at XXX.DemoTryCatch.getElement(DemoTryCatch.java:19)

at XXX.DemoTryCatch.main(DemoTryCatch.java:5)

finally代码块

格式

try{

...

}catch(异常类名 变量名) {

...

}

...catch(异常类名 变量名) {

...

}finally{

...

}

注意

finally不能单独使用,必须要和try一起使用

finally一般用于资源释放(资源回收),无论程序是否出现异常,最后都要释放IO

举例

public classDemoFinally {public static voidmain(String[] args) {try{

String[] strings={};

System.out.println(strings[100]);

}catch(ArrayIndexOutOfBoundsException e) {//获取异常的类型和异常描述信息

System.out.println(e.toString());

}finally{

System.out.println("程序执行完成");

}

}

}

控制台输出:

java.lang.ArrayIndexOutOfBoundsException:100程序执行完成

异常注意事项:多异常的捕获处理

多个异常分别处理

importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;public classDemo01ManyException {public static voidmain(String[] args) {try{int[] array = {1, 2, 3};int a = array[3];

}catch(ArrayIndexOutOfBoundsException e) {

System.out.println(e.toString());

}try{

List list = new ArrayList<>();

Collections.addAll(list,1, 2, 3);int b = list.get(3);

}catch(IndexOutOfBoundsException e) {

System.out.println(e.toString());

}

}

}

控制台输出:

java.lang.ArrayIndexOutOfBoundsException:3java.lang.IndexOutOfBoundsException: Index:3, Size: 3

多个异常一次捕获多次处理

importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;public classDemo01ManyException {public static voidmain(String[] args) {try{int[] array = {1, 2, 3};int a = array[3];

List list = new ArrayList<>();

Collections.addAll(list,1, 2, 3);int b = list.get(3);

}catch(ArrayIndexOutOfBoundsException e) {

System.out.println(e.toString());

}catch(IndexOutOfBoundsException e) {

System.out.println(e.toString());

}

}

}

控制台输出:

java.lang.ArrayIndexOutOfBoundsException:3

注意:一个try,多个catch,catch里面定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在前面,否则会报错

如ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException:

ddad42354ca427e88c9d6e6004888f60.png

ec5e46f2455001218eaeaecf2489cb7f.png

多个异常一次捕获一次处理

importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;public classDemo01ManyException {public static voidmain(String[] args) {try{int[] array = {1, 2, 3};int a = array[3];

List list = new ArrayList<>();

Collections.addAll(list,1, 2, 3);int b = list.get(3);

}catch(Exception e) {

System.out.println(e.toString());

}

}

}

控制台输出:

java.lang.ArrayIndexOutOfBoundsException:3

异常注意事项:finally有return语句

如果finally中有return语句,只会返回finally中的值。

如:

public classDemo01FinallyReturn {public static voidmain(String[] args) {

System.out.println(Demo01FinallyReturn.method());

}public staticString method() {try{

String s= "abc";returns;

}catch(Exception e) {

e.printStackTrace();

}finally{

String s= "ABC";returns;

}

}

}

控制台输出:

ABC

子父类异常

如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。

父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出。

如:

public classFu {public static void method1() throwsNullPointerException, ClassCastException { }public static void method2() throwsIndexOutOfBoundsException { }public static voidmethod3() { }public static voidmethod4() { }

}

public class Zi extendsFu {/*** 子类重写父类方法时,抛出和父类相同的异常

*@throwsNullPointerException 空指针异常

*@throwsClassCastException 类强制转换异常*/

public static void method1() throwsNullPointerException, ClassCastException { }/*** 子类重写父类方法时,抛出父类异常的子类

*@throwsArrayIndexOutOfBoundsException 索引越界异常*/

public static void method2() throwsArrayIndexOutOfBoundsException { }/*** 子类重写父类方法时,不抛出异常*/

public static voidmethod3() { }/*** 父类方法没有抛出异常,子类重写父类方法时,也不可以抛出异常

* 只能捕获处理,不能声明抛出*/

public static voidmethod4(){try{throw new Exception("编译期异常");

}catch(Exception e) {

e.printStackTrace();

}

}

}

自定义异常类的简单练习

要求

模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。

分析

1.使用数组保存已经注册过的用户名2.使用Scanner获取用户输入的注册的用户名3.定义一个方法,对用户输入中的注册用户名进行判断,遍历存储已经注册过用户名的数组,获取每一个用户名,

使用获取到的用户名和用户输入的用户名比较true:用户名已经存在,抛出 RuntimeException异常,告知用户"亲,该用户名已经被注册"

false:继续遍历比较。如果循环结束了,还没有找到重复的用户名,提示用户“恭喜您注册成功!"。

实现

importjava.util.Scanner;public classMyUsersException {private static String[] names = {"小红", "小明", "李华", "小军", "大雄"};public static voidregisterUser(String scannerUser) {for(String name : names) {if(name.equals(scannerUser)) {try{throw new RuntimeException("亲,该用户名已被注册!");

}catch(RuntimeException e) {

System.out.println(e.getMessage());return;

}

}

}

System.out.println("恭喜您注册成功!");

}public static void main(String[] args) throwsRuntimeException{

Scanner scn= newScanner(System.in);

System.out.print("输入要注册的用户名:");

String registerUserName=scn.next();

MyUsersException.registerUser(registerUserName);

}

}

控制台输入:李华

控制台输出:

亲,该用户名已被注册!

控制台输入:静香

控制台输出:

恭喜您注册成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值