通过异常处理错误

try - catch - finally的学习。和异常的初步认知。

定义:Java通过API中的Throwable类的众多子类描述各种不同的异常,所以java异常是Throwable子类的实例化对象。Throwable有两个重要的子类:ExceptionError

Error

Error错误代表了程序运行时Java系统内部的错误,与程序设计者的操作无关。 Error是不可查的 。

Exception

是程序本身可以处理的异常,程序设计者应尽量加以处理的部分。

Exception分为两类,一类是:运行时异常(RuntimeException)另一类是编译时异常(书上写的可称非运行时异常或已检查异常,是因为在Exception类中的子类只有RuntimeException是运行时异常。)

RuntimeException也是不可查异常。

对于不可查异常,编译器不会强制要求处理的异常,而编译时异常(非运行时异常),编译器会强制要求进行处理。

在这里插入图片描述

  • 常见的运行时异常(虽然编译也能通过,但是还是需要我们处理避免出现这些异常。)

ArrayIndexoutofBoundsException访问数组时使用无效索引值
NullPointException尝试访问null对象成员,空指针异常
ClassCastException类型转换异常
ArithmeticException非法的算术运算,如以0作除数
NumberFormatException数字转化格式异常
IllegalArgumentException方法接收到非法参数

这里测试一下ArithmeticException异常情况。

package com.Exception.Throws;

public class ArithmeticException {
    public static void main(String[] args) {
        int numA = 10;
        int numB = 0;
        int numC = 10;
        System.out.println(numA/numC);
        System.out.println(numA/numB);//这句是会报异常的。
        System.out.println(numA/numC);
    }
}

输出为:
在这里插入图片描述

这里就简单的测试了一下运行时异常。编译能通过,而且程序会正常运行,但是到了异常的语句,就会报错。(所以能输出1,但是异常后的语句就不能输出了。)

而且通过这个ArithmeticException可以进入这个类中看原码可以知道其实是调用了这其中的ArithmeticException(String message)方法下面可以演示一下。(只不过其中应该有规定了遇到分母为0所以会输出 / by zero

package com.Exception.RuntimeException;

public class ThrowsExceptionTest {
    public static void main(String[] args) {
        ArithmeticException a = new ArithmeticException("/ by zero");
        System.out.println(a);
    }
}

输出为:
在这里插入图片描述

看,是不是跟上面异常报错输出如出一辙。(这样看来是不是都能去原码中找的对应的方法使用。)

  • try - catch -finally的学习

一般例子为:

try {
    //可能出现异常的代码
}catch(异常类型1 变量名1) {
    //处理异常的方式1
}catch(异常类型2 变量名2) {
    //处理异常的方式2
}
....
finally {
    //一定会执行的代码
}
  • 首先观察一下是否可以省略。(先看没有异常(catch)的语句。)(finally是不管有没有try抛出异常,都执行的。)

package com.Exception.Throws.BianYiShiException;

public class ExceptionTry_Catch {
    public static void main(String[] args) {
        try {
            System.out.println("try");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 try {
            System.out.println("try");
        } finally {
     
 }

可以省略成这两种(在没有异常的情况下,不过没有异常我为什么还要写try-catch语句。。还没分析有异常情况下看能省略成什么样。)

public class ExceptionTry_Catch {
 public static int Sum() {
        try {
            int num = 10;
  //分别在try和finally中设置常量,这里主要是我想设置一个,看是否能互相使用发现会报错。
            return num;
        } finally {
            int num = 20;
            System.out.println(num);
        }
    }
    public static void main(String[] args) {
        
        System.out.println("finally的num:"+num);
        
    }

输出为:

finally的num:20
10

通过这个例子可以看出。

1、对于try返回的类型是需要有对应的。(比如这里的是intint num不然会报错)

2、设置的变量,常量在对应的作用域内才能使用。也就是说,即使这个tryfinally

一般连着使用,但是不共用属性。(如果需要是一个num呢)

 public static int Sum() {
        int num;//这里把num的定义写在了try和finally的外部,num指向的就是一个了。
        try {
            num = 10;
            System.out.println(num);
            num = 30;
            return num;
        } finally {
             num = 20;
            System.out.println("finally的num:"+num);
        }
    }

输出为:

10
finally的num:20
30

这样定义在外部,在try和finally中就不能再定义int num了(上面tryfinally中都可以定义是因为相当于在两个方法内。不同方法是可以定义同名的属性的,只不过一般为了避免混淆,所以不用同名。)

通过上面两个例子可以了解到:try ,finally 语句是顺序执行的,不过return是最后再return输出的。如果在finally语句中也使用return

 public static int Sum() {
        int num;//这里把num的定义写在了try和finally的外部,num指向的就是一个了。
        try {
            num = 10;
            System.out.println(num);
            num = 30;
            return num;
        } finally {
             num = 20;
            System.out.println("finally的num:"+num);
             return num;
        }
    }

输出为:

10
finally的num:20
20

上面return的地方都是参数。如果return为方法呢?会先输出方法中的语句还是最后return来输出?

package com.Exception.Throws.BianYiShiException;

public class Demo1_1 {
    //写一个含try和finally的方法类型为String(为了后续输出对应。)
    public static String Fun() {
        try {
            System.out.println("try");//----------1
            return FunctionM();//进入这个方法中。
        } finally {
            System.out.println("finally");//-------------4
        }
    }
	//用try来调用FunctionM方法看输出顺序如何?
    public static String FunctionM() {
        System.out.println("FunctionM方法中的输出语句。");//--------2
        System.out.println(FunctionN("成功在return “pz” 前输出"));//----------3
        //顺序执行。
        return FunctionN("pz");//-------------5
    }
	//通过上一步方法来继续return一个方法,进一步测试输出顺序。
    public static String FunctionN(String name) {
        return name;
    }

    public static void main(String[] args) {
        System.out.println(Fun());
    }
}


输出为:

try
FunctionM方法中的输出语句。
成功在return “pz” 前输出
finally
pz

通过上面三个例子可以发现,语句是按顺序执行,如果遇到了return,会进去执行其中的方法语句,执行到遇到return为止。然后跳到finally语句中输出,再return最后调用得到的数据。(如果return为方法的话)。

如果在finally语句中添加一个return语句的话。

package com.Exception.Throws.BianYiShiException;

public class Demo1_1 {
    public static String Fun() {
        try {
            System.out.println("try");
            return FunctionM();
        } finally {
            System.out.println("finally");
            return "lxm";
            //区别就是这里加上了一句return。
        }
    }

    public static String FunctionM() {
        System.out.println("FunctionM方法中的输出语句。");
        System.out.println(FunctionN("成功在return “pz” 前输出"));
        return FunctionN("pz");
    }

    public static String FunctionN(String name) {
        return name;
    }

    public static void main(String[] args) {
        System.out.println(Fun());
    }
}

输出为:

try
FunctionM方法中的输出语句。
成功在return “pz” 前输出
finally
lxm

最后返回的值就变成了finally语句中的return的值了。这里可以看出,还是不要在finally语句中加上return的好,不然可能会导致,try的语句输出不完全,而直接输出finally的返回值(数据就有可能不是try或catch中的值了)。

  • Catch的输出

package com.Exception.Throws.BianYiShiException;

public class CatchTest1_1 {
    public static void main(String[] args) {
        try {
            int a = 10;
            int b = 0;
            System.out.println(a/b);
        } catch (Exception e) {
            e.getMessage();
            System.out.println(e);
        }

    }
}

输出为:

java.lang.ArithmeticException: / by zero

这里就跟上面我直接调用ArithmeticException方法输出语句一样了。

如果换成这种:

 catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);//这个是下面那个输出语句。
        }

输出为:(这里跟我直接使用ArithmeticException不同的是,报错以后,这里语句还能输出。)

在这里插入图片描述
上面输出过程都是有异常的前提,这里再做没有异常的测试。

package com.Exception.Throws.BianYiShiException;

public class CatchTest1_1 {
    public static void main(String[] args) {
        try {
            int a = 10;
            int b = 0;
            System.out.println("1");//如果这里没有报错呢?
        } catch (Exception e) {
            e.getMessage();
            System.out.println(e);
        }
    }
}

输出为:

1
package com.Exception.Throws.BianYiShiException;

public class CatchTest1_1 {
    public static void main(String[] args) {
        try {
            int a = 10;
            int b = 0;
            System.out.println("1");//如果这里没有报错呢?
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("错误");
        }
    }
}

输出也为:

1

getMessage():返回该异常的详细字符串。

printStackTrace():将异常事件的跟踪栈信息输出。建议在捕获到异常时总使用该方法将跟踪栈信息打印输出到控制台。

还有抛出异常,对于多重异常的学习(内外层异常的捕获和处理)。
和throw之后怎么样才能让语句正常执行,有时是编译都不能通过,有时又是语句不能正常输出。

 开通会员以解锁全部内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值