运行 单元测试时,Jacoco 在我的界面中添加了一个 $jacocoInit 方法

Jacoco is adding a $jacocoInit method in my interface when running unit tests

在接口中添加默认方法时,我得到了一个不必要的方法 $jacocoInit。我的界面如下所示:

@Value.Immutable
public interface Customer {


    Optional<@NotBlank String> name();

    default Object getObject(final String abc) {
        return null
    }

    default void getObject() {

    }
}

当我在做的时候

for (Method method : Customer.class.getDeclaredMethods()) {
    System.out.println(method.getName());
}

那么,我得到

name
getObject
$jacocoInit

如果我从中删除默认方法,那么它就不会使用 $jacocInit 方法。我不确定为什么会这样?有人可以帮忙吗?

根据JaCoCo FAQ

To collect execution data JaCoCo instruments the classes under test which adds two members to the classes: A private static field $jacocoData and a private static method $jacocoInit(). Both members are marked as synthetic.

Please change your code to ignore synthetic members. This is a good practice anyways as also the Java compiler creates synthetic members in certain situation.

Method isSynthetic of class java.lang.reflect.Method

Returns true if this executable is a synthetic construct; returns false otherwise.

所以要忽略合成成员:

for (Method method : Customer.class.getDeclaredMethods()) {
    if (method.isSynthetic()) {
        continue;
    }
    System.out.println(method.getName());
}

这里是 Java 编译器创建合成方法的众多示例之一:

import java.lang.reflect.*;

class Example {

    interface I {
        Runnable r = () -> {}; // lambda

        void m();
    }

    public static void main(String[] args) {
        for (Method method : I.class.getDeclaredMethods()) {
            System.out.println("name: " + method.getName());
            System.out.println("isSynthetic: " + method.isSynthetic());
            System.out.println();
        }
    }
}

使用JDK1.8.0_152执行

javac Example.java
java Example

产生

name: m
isSynthetic: false

name: lambda$static[=13=]
isSynthetic: true

这就是 Java Virtual Machine Specification states about synthetic members:

A class member that does not appear in the source code must be marked using a Synthetic attribute, [...]

您可以在 its documentation and in presentations done by JaCoCo team 中阅读有关 JaCoCo 实现的更多信息,其中还包括一些其他合成构造示例。