加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 代码覆盖最终阻止

发布时间:2020-12-14 16:18:20 所属栏目:Java 来源:网络整理
导读:我有以下代码构造: try { //some code}catch(CustomException custExc) { //log}catch(CustomException2 custExc2) { //log}catch(Exception exc) { //log}finally { //some code} 我写了单元测试:第一个是在不抛出异常的情况下覆盖的情况(仅执行块代码,最
我有以下代码构造:
try {
   //some code
}
catch(CustomException custExc) {
  //log
}
catch(CustomException2 custExc2) {
  //log
}
catch(Exception exc) {
  //log
}
finally {
  //some code
}

我写了单元测试:第一个是在不抛出异常的情况下覆盖的情况(仅执行块代码,最后阻止代码),另外3个是同时覆盖每个catch块的(执行try块,catch阻止并最终阻止).
问题是Eclipse Emma插件显示我没有覆盖最后的块.任何想法为什么会发生?

解决方法

在Java字节码(至少从Java 1.6开始)之后,finally块没有特殊的构造,所以实际上重复了很多次.例如,考虑以下方法:
public static void main(String[] args) {
    try {
        System.out.println("In try");
        if(args.length > 0)
            return;
        System.out.println("No args");
    }
    catch(RuntimeException ex) {
        System.out.println("In catch");
    }
    finally {
        System.out.println("In finally");
    }
}

此代码有效地编译成如下所示:

public static void main(String[] args) {
    try {
        System.out.println("In try");
        if(args.length > 0) {
            System.out.println("In finally");
            return;
        }
        System.out.println("No args");
    }
    catch(RuntimeException ex) {
        System.out.println("In catch");
        System.out.println("In finally");
    }
    catch(<any exception> t) {
        System.out.println("In finally");
        throw t;
    }
    System.out.println("In finally");
}

这不是一个完全等效的代码,因为如果在System.out.println(“In finally”)期间发生新的异常; (返回之前),那么它不会被捕获.然而,它显示了这个粗略的想法,finally块在这里重复了四次.如果您有几种方法可以退出尝试块,特别是如果您有嵌套的try-finally块,则可以复制更多次.另请注意< any exception>特别追加.即使你明确地写了catch(Throwable t),它也会出现在字节码中.

由于像Emma或JaCoCo这样的代码覆盖工具在字节码级别上工作,他们并不知道这四个“In finally”printlns在源代码中实际上是一样的语句.可以执行字节码分析,并且相当鲁棒地确定字节码的哪个部分对应于单个源最终阻止(我实际上写了这样的分析器一次),但这不是很容易的问题,并且具有一些不平凡的注意事项.您还应该考虑到不同的编译器(例如,javac和ecj)会产生一些不同的finally块布局.所以似乎这个工作没有在流行的覆盖工具中完成,他们只是将不同的最终块拷贝视为不同的代码.

在你特定的情况下,@bobbel是正确的:你没有测试未捕获的异常情况(< any exception> catch).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读