简体   繁体   English

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

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

I am getting a unnecessary method $jacocoInit when adding the defaut method in interface.在接口中添加默认方法时,我得到了一个不必要的方法 $jacocoInit。 My interface looks like this:我的界面如下所示:

@Value.Immutable
public interface Customer {


    Optional<@NotBlank String> name();

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

    default void getObject() {

    }
}

When I am doing当我在做

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

then, I am getting然后,我得到

name
getObject
$jacocoInit

If I remove the default method from it, then it does not $jacocInit method.如果我从中删除默认方法,则它不会 $jacocInit 方法。 I am not sure why it is happening?我不确定为什么会这样? Can someone please help in this?有人可以帮忙吗?

According to JaCoCo FAQ :根据JaCoCo 常见问题解答

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() .为了收集执行数据,JaCoCo 对被测类添加了两个成员:私有 static 字段$jacocoData和私有 static 方法$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.无论如何,这是一个很好的做法,因为 Java 编译器也会在某些情况下创建合成成员。

Method isSynthetic of class java.lang.reflect.Method 方法是合成isSynthetic java.lang.reflect.Method

Returns true if this executable is a synthetic construct;如果此可执行文件是合成构造,则返回 true; returns false otherwise.否则返回 false。

So to ignore synthetic members:所以忽略合成成员:

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

And here is one of many examples where Java compiler creates synthetic method:这是 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();
        }
    }
}

Using JDK 1.8.0_152 execution of使用JDK 1.8.0_152执行

javac Example.java
java Example

produces生产

name: m
isSynthetic: false

name: lambda$static$0
isSynthetic: true

And here is whatJava Virtual Machine Specification states about synthetic members :以下是Java 虚拟机规范关于合成成员的说明:

A class member that does not appear in the source code must be marked using a Synthetic attribute, [...]未出现在源代码中的 class 成员必须使用 Synthetic 属性进行标记,[...]

You can read more about JaCoCo implementation in its documentation and in presentations done by JaCoCo team , which also include some other examples of synthetic constructions.您可以在 JaCoCo的文档JaCoCo 团队完成的演示文稿中阅读有关 JaCoCo 实现的更多信息,其中还包括一些合成构造的其他示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM