【Java之轨迹】第五章:异常总结


◉ 异常与错误

错误(Error) 是程序中遇到的使整个程序崩溃的情况,有的能在编译阶段被发现,如 死循环 能被IDEA发现;有的在运行阶段出现,如:内存泄漏

异常(Exception) 是程序中不可避免但可以预先知道并处理的情况。


◉ 异常的分类

异常分为两种:

  • 运行时异常(RuntimeException): 在运行时出现的异常
    用户输入异常数值除0异常
    这种异常在编译时可以不作处理,发现错误后直接交给虚拟机JVM处理并结束程序
  • 必检查异常(CheckedException): 这是在编译阶段就会要求处理的异常,否则编译不通过,如 IO流异常中的 文件找不到异常
    这种异常要求程序员必须先做出处理

◉ 异常的处理

处理方式也有两种:

  • try-catch-finally 处理: 对可能出现异常的语句放在 try 中,把异常出现后应该做出的动作放在 catch 中,最后把需要释放的资源放在 finally 中
    这样使得即使异常出现,也不会直接交给虚拟机JVM,程序不会中止继续执行
  • throws 抛出异常: 如果不知道如何处理或者不想处理异常,可以将异常抛给上级调用者,由调用者进行 try-catch 处理
    但当调用者一个一个都不想处理都往外抛的话,最终会抛给虚拟机JVM处理,这时如果异常出现就只能程序中止了

try-catch-finally 处理

public static void main(String[] args) {
    File file = new File("D://test.txt");
    InputStream is = null;
    try {
        is = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        System.out.println("找不到此文件!");
    }finally
    {
        if(is!=null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这是一个必检查的IO异常

  • try 中可能存在的异常是 FileNotFoundException 文件找不到异常(如文件名写错了)
  • catch 中打印出错误提示,也可以用 e.printStackTrace(); 打印异常信息。
  • finally 中释放了资源,由于又使用到 IO 流,还得加上一个处理 IO 的异常

try-with-resources 语句

JDK7 以后,资源释放可以放在 try 的括号中,简写成:

public static void main(String[] args) {
    File file = new File("D://test.txt");
    try (
            InputStream is = new FileInputStream(file);
            /* 资源 ... */
    ) {
        /* 操作资源 ... */
    } catch (FileNotFoundException e) {
		System.out.println("找不到此文件!");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

需要释放的资源可以放在 try 后边的括号中,等运行完毕后资源会自动被释放掉
括号中资源的作用域依旧是整个 try 块

catch 可以有多个,且先出现的是小异常,大异常必须在后面出现
IOExceptionFileNotFoundException 的父类,它放在前面会导致编译不通过。也可以只写 IOException 一个,就能捕获到它及所有子类的异常了

通常可以小异常在前,最后加一个 Exception 捕获所有异常
这种写法可以对已经预测的异常做出相应处理,对可能遗漏的异常进行捕捉

throws 处理

public static void main(String[] args) {
    try {
        test();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void test() throws IOException
{
    File file = new File("D://test.txt");
    InputStream is = new FileInputStream(file);
    /* 操作资源 ... */
}

将异常抛出,调用时再处理异常
main 方法中可再次将异常抛出,这次由于 mian 方法由虚拟机JVM的调用,所以是直接抛给虚拟机,如果异常出现程序将中止

public static void main(String[] args) throws IOException {
    test();
}

◉ 自定义异常

定义方式:

public class MyException extends RuntimeException
{
    // 添加一个无参构造器
    public MyException()
    {
        super();
    }

    // 添加一个带信息的构造器
    public MyException(String message)
    {
        super(message);
    }
}

将类继承 Exception 或 RuntimeException 或者其他子类
区别是继承 RuntimeException 为非必须检查异常,除此之外都必须检查

使用:

public static void main(String[] args) throws MyException{
    test(-1);
}

public static void test(int a)
{
    if(a<0) throw new MyException("不能小于0");
}

throw 用于创建一个异常。这里直接抛出了
注意:RuntimeException 可以不显示写上 throws ,只要没有用 try-catch 进行捕获,就会默认抛出。就如上面一样没有写throws默认抛出(main 后边的 throws 也可不写)

public static void test(int a)
{
    try {
        if(a<0)
            throw new MyException("不能小于0");
    }catch (MyException e) {
        /* 处理 ... */
    }
}

也可以直接捕获,不过通常是直接抛出


◉ finally 的执行机制(面试)

注意 finnally 的执行机制:
无论是 try 执行还是 catch 执行,finally 都会在最后执行一次。
哪怕在 try 和 catch 中有 return 语句,在执行到 return 语句时,都会先放弃然后去执行 finally 语句,直到 finally 执行完毕后再回去执行 return 语句
所以在 finally 中最好不写 return 语句,执行顺序没把握好就会出现奇怪的事
但,如果再 try 或者 catch 中遇到了 exit ,那么 finally 中的代码就不会执行了

ublic static void main(String[] args) {

        System.out.println(test(2));
    }

    public static int test(int a)
    {
        try {
            if(a<0) {
                throw new MyException("不能小于0");
            }
            return a;
        }catch (MyException e) {
            /* 处理 ... */
            return -1;
        }finally
        {
            System.out.println("haha");
        }
    }
运行结果:
haha
2

◉ throws 和 throw 的区别

  • throws 写在方法名的括号后面,表示抛出一个异常给上级调用者
  • throw 写在方法体中,表示创建一个异常对象供以使用。常用于手动抛出(自己定义的)异常

◉ final,finally 和 finalize 的区别

  • final 用于声明,表示被声明的 属性、方法和类 一旦复制便不可以再被改变
  • finally 是异常处理的一部分,表示无论异常与否总会被执行,常用来释放资源等善后处理
  • finalize 是Object类的一个方法,垃圾回收器在回收对象时,会调用被回收对象的这个方法,相当于 垃圾的遗言 ,在垃圾被回收时最后做的善后处理

◉ 面试常见异常

非运行时异常

IOException 输入输出异常
ClassNotFoundException 找不到类异常

运行时异常

ArrayIndexOutOfBoundsException 数组越界异常,如:

int[] a = new int[2];
a[3] = 1;

ArithmeticException 算数运算异常,如:除0

System.out.println(1/0);

ArrayStoreException 数组存储异常,如:

Object[] o = new String[2];
o[0] = new Integer(1);

NullPointerException 空指针异常,如:

String a = null;
a.toString();

ClassCastException 强制类型转化异常,如:

Object o = new String();
Integer i = (Integer) o;

粼粼水波,沙沙作响,捕捉到微风异常!(寒冰小澈)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒冰小澈IceClean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值