Jacoco插装后$jacocoInit()方法实现

本文探讨了JaCoCo代码覆盖率工具的插桩原理,特别是$jacocoInit()方法的实现。在反编译的代码中,注意到一个Long类型的变量被强制转换为boolean[],这是通过JaCoCo的特殊方法RuntimeData.equals()完成的,该方法会修改数组内容。$jacocoInit()用于初始化静态的boolean数组,用于跟踪代码执行情况。
摘要由CSDN通过智能技术生成

最近看了下Jacoco源码,对插装后的代码反编译,有看到定义$jacocoInit()方法,但无法反编译具体实现。通过阅读官方文档以下说明:

Object access = ...                          // Retrieve instance

Object[] args = new Object[3];
args[0] = Long.valueOf(8060044182221863588); // class id
args[1] = "com/example/MyClass";             // class name
args[2] = Integer.valueOf(24);               // probe count

access.equals(args);

boolean[] probes = (boolean[]) args[0];

对于以上的实现非常困惑,args[0]是Long类型怎么能强制转换为boolean[]呢。

Jacoco是通过插入JVM指令实现$jacocoInit()的,其中有个equals的方法特别容易让人难以理解,equals内部对数组进行了修改。通过对JVM指令的还原,伪代码示意如下。

public class User {
    private static transient boolean[] $jacocoData;
    
    private String name;

    public User(String name) {
        boolean[] var2 = $jacocoInit();
        super();
        this.name = name;
        var2[0] = true;
    }

    public String getName() {
        boolean[] var1 = $jacocoInit();
        var1[1] = true;
        return this.name;
    }

    public void setName(String name) {
        boolean[] var2 = $jacocoInit();
        this.name = name;
        var2[2] = true;
    }

    private static boolean[] $jacocoInit() {
        if($jacocoData != null){
            return $jacocoData;
        }
        
        { // 如果使用:SystemPropertiesRuntime存储执行信息,会从以下方式获取
            java.util.Properties properties = java.lang.System.getProperties();
            RuntimeData data = (RuntimeData)properties.get("key+hashcode()");
            Object[] args = new Object[3];
            args[0] = Long.valueOf(8060044182221863588); // class id
            args[1] = "com/example/MyClass";             // class name
            args[2] = Integer.valueOf(24);               // probecount
            // 特殊方法,会修改args[0] 的值,参考RuntimeData.equals()
            data.equals(args);
            $jacocoData =  (boolean[])args[0];
        }
        return $jacocoData;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值