Java面试题-Java核心基础-第八天(异常)

目录

一、异常类的层级结构

二、受检异常和非受检异常的区别

三、throw和throws的区别

四、try-catch-finally的使用

五、finally一定会执行吗

六、异常的底层

七、Java7的try-with-resource

八、Throwable类的常用方法

九、使用异常机制需要注意那些?


一、异常类的层级结构

Java中的异常其实一般来说是说的Exception异常,这是微观的,其实宏观上面的异常还包括Error

反正就是不正常。注意Java中的异常并不是代码的语法错误,而是说为了预防运行时出现错误,或者是运行时出现错误

宏观上面的异常分为两个大类:

总的来说都是Throwable类下面的两个子类

Error和Exception

Error指的是错误,一些无法直接解决的错误,通常是很严重的错误,会导致程序无法正常运行

比如是 OOM内存溢出  StackOverFlow栈溢出等异常

而Exception是异常,可以直接解决的,分为编译时异常也叫做受检异常和运行时异常也叫非受检异常

编译时异常时为了预防程序发生错误而出现了这么一种异常,当抛出了编译时异常,则编译器不能让你通过,必须得手动的处理掉这个异常(try-catch或者失败throws的方式)。

常见的编译时异常有:

FileNotFountException和ClassNotFoundException、SQLExcption

而运行时异常则是当程序真正的执行出错了抛出的异常,RuntimeException及其子类异常都是运行时异常,否则就是编译时异常  常见的运行时异常有:

NullPointException空指针异常、IndexOutOfBoundsException数组越界异常

ClassCastException 类型转换异常、NumberFormatException字符串转换异常、ArithmaticExcepion算数异常等

二、受检异常和非受检异常的区别

受检异常必须手动将其处理掉,否则编译器都不能让你通过 它是为了避免出现异常的这么一种异常

而运行时异常可以不处理  它可以指定程序执行时候出现的错误

其实两者都是要程序真正执行才能产生异常。只是说一个是预防,不管有没有提前就需要处理

而另外一个则是可以不急着处理,因为这类异常并不是很频繁,当真正出现了问题再去修改即可

就好像说 因为下雨其实是经常的所以需要提前备好雨伞,但是像地震就发生得少,所以可以不急着预防

三、throw和throws的区别

throw是抛出一个异常是产生异常

throws是将将异常进行处理,将异常抛出给调用者

四、try-catch-finally的使用

try块中是放代码,如果里面出现了异常,交由catch块处理,而finnaly则是一定会执行的代码

注意:再try或者是再catch中有return的话  那么先将结果存到本地变量中,然后执行完finnally在返回。如果说再finally中有return的话那么会覆盖掉之前的结果

五、finally一定会执行吗

不一定  当在之前调用了System.exit方法或者是cpu关闭或者是当前线程死亡就不能执行

六、异常的底层

public static void simpleTryCatch() {
   try {
       testNPE();
   } catch (Exception e) {
       e.printStackTrace();
   }
}

通过查看字节码指令就会知道,有一个异常表:

//javap -c Main
 public static void simpleTryCatch();
    Code:
       0: invokestatic  #3                  // Method testNPE:()V
       3: goto          11
       6: astore_0
       7: aload_0
       8: invokevirtual #5                  // Method java/lang/Exception.printStackTrace:()V
      11: return
    Exception table:
       from    to  target type
           0     3     6   Class java/lang/Exception
  • from 可能发生异常的起始点
  • to 可能发生异常的结束点
  • target 上述from和to之前发生异常后的异常处理者的位置
  • type 异常处理者处理的异常的类信息

七、Java7的try-with-resource

这个是简化之前的try-finally的 

这个只要流实现了Closeable接口或者是AutoCloseable接口 都能自动的关闭资源 然后执行catch或者是finally中的语句 而不需要我们再手动的写关闭资源的代码 

语法也就是直接将流的声明写在try的()后面,多个用逗号分隔

try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));
     BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {
    int b;
    while ((b = bin.read()) != -1) {
        bout.write(b);
    }
}
catch (IOException e) {
    e.printStackTrace();
}

八、Throwable类的常用方法

toString:显示异常对象的详细信息

getMessage:显示异常的简要信息

getLocalizedMessage:显示异常的本地化信息,如果其Throwable的子类覆盖了这个方法,那么就能生成本地化信息,否则和getMessage相同

printStackTrack:打印异常对象封装的异常堆栈信息

九、使用异常机制需要注意那些?

1. 异常信息一定要有意义

2. 抛出的异常应该具体一点  比如说能抛出NumberFormatException就不要抛出IllegalArgumentException

3. 使用日志打印异常之后就不要再抛出异常了

4. 不要将异常定义为静态的,这样会使得异常的栈信息混乱,应该使用throw new的方式

手动的抛出异常对象。

比如说下面这个例子:


public class Exceptions {
    public static BusinessException ORDEREXISTS = new BusinessException("订单已经存在", 3001);
...
}


@GetMapping("wrong")
public void wrong() {
    try {
        createOrderWrong();
    } catch (Exception ex) {
        log.error("createOrder got error", ex);
    }
    try {
        cancelOrderWrong();
    } catch (Exception ex) {
        log.error("cancelOrder got error", ex);
    }
}

private void createOrderWrong() {
    //这里有问题
    throw Exceptions.ORDEREXISTS;
}

private void cancelOrderWrong() {
    //这里有问题
    throw Exceptions.ORDEREXISTS;
}

结果:


[14:05:25.782] [http-nio-45678-exec-1] [ERROR] [.c.e.d.PredefinedExceptionController:25  ] - cancelOrder got error
org.geekbang.time.commonmistakes.exception.demo2.BusinessException: 订单已经存在
  at org.geekbang.time.commonmistakes.exception.demo2.Exceptions.<clinit>(Exceptions.java:5)
  at org.geekbang.time.commonmistakes.exception.demo2.PredefinedExceptionController.createOrderWrong(PredefinedExceptionController.java:50)
  at org.geekbang.time.commonmistakes.exception.demo2.PredefinedExceptionController.wrong(PredefinedExceptionController.java:18)

实际上我们需要的是create方法的日志记录应该是createOrder got error而非cancelOrder got error

就造成不匹配的混乱情况

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值