Java中的小知识 ---- 异常

代码中的异常

Throwable类:Java中所有异常的超类,在Java中的所有异常,错误的基类都是Throwable类。

Throwable类包含两个大类:

Exception:异常;可以处理,代码还能拯救
Error:错误;代码不能运行

Throwable类中的常用方法

Constructor:
    Throwable(); Throwable构造方法,Throwable类对象中,存储的异常或者错误信息为null
    Throwable(String message);Throwable构造方法,Throwable类对象中,存储的异常或者错误信息
                              为message 
Method:
    String getMessage();获取Throwable对象中存储的异常或者错误信息
    String toString();返回当前异常或者错误的简要描述
    void printStackTrace();展示错误的前因后果,【是红色字体】
package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 19:45
 */
public class Demo1 {
    public static void main(String[] args) {
        Throwable throwable = new Throwable();
        System.out.println(throwable.getMessage());
        System.out.println(throwable.toString());
        throwable.printStackTrace();
    }
}

输出结果:

null
java.lang.Throwable
java.lang.Throwable
	at com.wcc.a_throwable.Demo1.main(Demo1.java:9)

另外:

package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 20:07
 */
public class Demo3 {
    public static void main(String[] args) {
        test(10,0,null);
    }
    public static void test(int num1, int num2,int[] arr){
        int ret = 0;
        try{
             ret = num1 / num2;
            System.out.println("测试代码");
            arr[0] = 10;
        }catch (ArithmeticException e){
            System.out.println("发生了算术异常");
        }catch (NullPointerException e){
            System.out.println("发生了空指针异常");
        }
        System.out.println("ret: " + ret);
    }
}
//执行结果:
/*
发生了算术异常
ret: 0
*/
//因为代码在捕获到第一个异常之后,try内剩余的代码就不再执行了

Error和Excption的区别

Exception:异常,可以处置
Error:错误,不可以处置,只能避免
package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 19:54
 */
public class Demo2 {
    public static void main(String[] args) {
        int[] arr = null;
        arr[0] = 10;
    }
}
//一个Exception:
//Exception in thread "main" java.lang.NullPointerException
//	at com.wcc.a_throwable.Demo2.main(Demo2.java:10)
package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 19:54
 */
public class Demo2 {
    public static void main(String[] args) {
     test();
    }
    public static void test(){
        long[] longs = new long[1024];
        test();
    }
}
/*
    执行结果:

Exception in thread "main" java.lang.StackOverflowError
	at com.wcc.a_throwable.Demo2.test(Demo2.java:13)

这就是一个错误
*/

异常处理

捕获异常

我的手割破了一个小口子,去医院门诊部包扎好,这就叫捕获异常

try - catch 结构
try - catch - finally 结构(本文暂不讲解)

格式:

try{

    有可能出现异常的代码

} catch(对应处理的异常对象){

    处理方式

}

举个栗子:

package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 20:07
 */
public class Demo3 {
    public static void main(String[] args) {
        test(10,0);
    }
    public static void test(int num1, int num2){
        int ret = num1 / num2;
    }
}
//这份代码没有使用try - catch捕获
/*
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.wcc.a_throwable.Demo3.test(Demo3.java:12)
	at com.wcc.a_throwable.Demo3.main(Demo3.java:9)
*/
package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 20:07
 */
public class Demo3 {
    public static void main(String[] args) {
        test(10,0);
    }
    public static void test(int num1, int num2){
        int ret = 0;
        try{
             ret = num1 / num2;
        }catch (ArithmeticException e){
            System.out.println("发生了算术异常");
        }
        System.out.println("ret: " + ret);
    }
}
//这份是采用了try - catch捕获之后的代码
//当代码被捕获了之后,编译器会认为改代码没有异常,而继续往下执行
//输出结果:
/*
发生了算术异常
ret: 0
*/

另外:

package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 20:07
 */
public class Demo3 {
    public static void main(String[] args) {
        test(10,0,null);
    }
    public static void test(int num1, int num2,int[] arr){
        int ret = 0;
        try{
             ret = num1 / num2;
            System.out.println("测试代码");
            arr[0] = 10;
        }catch (ArithmeticException e){
            System.out.println("发生了算术异常");
        }catch (NullPointerException e){
            System.out.println("发生了空指针异常");
        }
        System.out.println("ret: " + ret);
    }
}
//输出结果:
/*
发生了算术异常
ret: 0
*/
//这是因为,在捕获了第一个异常ret之后,try内的代码就不再执行了

总结:

1.代码中从异常发生位置开始,try内之后的代码不再运行
2.代码中有多个异常,可以使用多个catch捕获,分门别类处理
3.当前情况下,只能展示异常情况,后期可以将异常情况做成log日志文件
4.当异常被捕获之后,代码可以正常运行

 

抛出异常

我胳膊骨折了,去医院门诊部,门诊部让我去骨外科医治,这就叫抛出异常

throw
    在方法内抛出异常
throws
    在【方法声明】位置,告知调用者当前方法有哪些异常抛出
    声明的异常需要生成对应的文档注释
package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 20:32
 */
public class Demo4 {
    //这是异常抛出处理,调用带有异常抛出的方法,如果选择继续抛出需要在当前方法的声明位置
    //告知其他调用者,这里有什么异常抛出
    public static void main(String[] args)
            throws ArithmeticException,NullPointerException {
        //调用一个带有异常的方法
        //捕获处理
        try{
            test(10,2,null);
        }catch (ArithmeticException e){
            System.out.println(e.getMessage());
        }catch (NullPointerException e){
            System.out.println(e.getMessage());
        }

    }

    /**
     * 测试方法
     * @param num1 int类型
     * @param num2 int类型
     * @param arr int类型数组
     * @throws ArithmeticException 除数不能为0
     * @throws NullPointerException 操作数组null地址异常
     */
    public static void test(int num1, int num2, int[] arr)
            throws ArithmeticException,NullPointerException{
        if(0 == num2){
            //可能存在算术异常
            throw new ArithmeticException("算术异常");
        }
        if(null == arr){
            //可能存在空指针异常
            throw new NullPointerException("空指针异常");
        }
        System.out.println(num1 / num2);
        arr[0] = 10;
    }
}
/*
    抛出异常总结:
        1.一个代码块内有且只能抛出一个异常
        2.从throw位置开始,之后的代码不在运行
        3.代码中存在使用throw抛出异常,那么在方法的声明位置,必须告诉调用者有什么异常


*/

异常抛出和捕获的对比

捕获之后,代码可以正常运行,那么就要保证处理之后的错误不会再导致其他错误。
例如:
    用户名密码错误,不能采用捕获异常;因为捕获了之后,代码可以正常运行,不能用户名密码都
    错误了,还能进入系统。
抛出异常的确可以解决很多问题,并且可以让代码健壮性很强,但是到了用户层面,绝对不能抛,
不能用户密码输入错误,你把错误日志发给用户看。可以用其他方式,告知用户密码输入错误。
用户密码错误时:
    1.捕获异常
    2.通过异常处理,catch将异常抛出
    3.给予用户友好提示

运行时异常RuntimeException

不需要抛出,代码运行之后会自动识别该异常
例如:
    ArrayIndexOfBoundException;
    NullPointException;
    StringIndexOfBoundException;
    ArithmeticException;
这些异常在代码中如果出现,在代码中不需要强制进行捕获或者抛出

自定义异常

代码运行过程中存在一些生活化异常:
    用户名密码错误
自定义异常格式:
    class 自定义异常名 extends Exception{
        No Fileds Constructor
        String Field Constructor
}
自定义异常类名:必须以Exception结尾!

代码演示:

package com.wcc.a_throwable;

/**
 * @Author kk
 * @Date 2020/3/12 21:17
 */

/**
 * 自定义异常
 */
class NoGirlFriendException extends Exception{
    /**
     * 无参构造方法
     */
    public NoGirlFriendException(){}

    /**
     * 带有String类型参数的构造方法
     * @param message 描述当前异常信息
     */
    public NoGirlFriendException(String message){
        super(message);

    }
}
public class Demo5 {
    public static void main(String[] args) throws NoGirlFriendException {
        buyOneFreeOne(true);
    }

    /**
     * 买一送一方法,需要判断是不是单身狗
     * @param singleDog boolean数据,true表示单身,false表示有女朋友
     * @throws NoGirlFriendException 没有女朋友异常
     */
    public static void buyOneFreeOne(boolean singleDog) throws NoGirlFriendException {
        if (singleDog) {
            throw new NoGirlFriendException("两只黄鹂鸣翠柳,你还没有女朋友");
        }
        System.out.println("买甜筒,送保时捷一辆");
        }
    }

运行结果:

Exception in thread "main" com.wcc.a_throwable.NoGirlFriendException: 
两只黄鹂鸣翠柳,你还没有女朋友
	at com.wcc.a_throwable.Demo5.buyOneFreeOne(Demo5.java:38)
	at com.wcc.a_throwable.Demo5.main(Demo5.java:28)
发布了23 篇原创文章 · 获赞 34 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42597414/article/details/104826080