【问题标题】:Strange Default Method behavior with different Java versions不同 Java 版本的奇怪默认方法行为
【发布时间】:2016-05-08 23:45:02
【问题描述】:

假设我有以下类层次结构:

interface Collection<E>
{
    Collection<E> $plus(E element)
}

interface MutableCollection<E> extends Collection<E>
{
    @Override
    MutableCollection<E> $plus(E element)
}

interface Set<E> extends Collection<E>
{
    @Override
    Set<E> $plus(E element)
}

interface MutableSet<E> extends Set<E>, MutableCollection<E>
{
    @Override
    default MutableSet<E> $plus(E element)
    {
        // ... implementation
    }
}

abstract class AbstractArraySet<E> implements Set<E>
{
    // ... no $plus(...) implementation
}

class ArraySet<E> extends AbstractArraySet<E> implements MutableSet<E>
{
    // ... no $plus(...) implementation
}

如您所见,只有MutableSet 类提供了$plus 方法的实现。在测试用例中,我在 ArraySet 类型的实例上调用此方法。测试总是在 CI 环境中通过,而在我的本地环境中它总是以 AbstractMethodError 失败。在这两种情况下,我都使用 Gradle (2.7)。


错误:

java.lang.AbstractMethodError: Method dyvil/collection/mutable/ArraySet.$plus(Ljava/lang/Object;)Ldyvil/collection/Collection; is abstract

    at dyvil.collection.mutable.ArraySet.$plus(ArraySet.java)
    at dyvil.tests.CollectionTests.testCollection(CollectionTests.java:99)
    at ...

Test Code:

testCollection(new ArraySet());

public void testCollection(Collection collection)
{
    assertEquals(mutable.$plus("newElement"), collection.$plus("newElement"));
}

java -version 输出:

  • CI(在哪里工作):

    java version "1.8.0"
    Java(TM) SE Runtime Environment (build 1.8.0-b132)
    Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
    
  • 本地(失败的地方):

    java version "1.8.0_71"
    Java(TM) SE Runtime Environment (build 1.8.0_71-b15)
    Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, mixed mode)
    

我预计这是某种javac 错误,编译器无法添加所有必需的桥接方法(代码编译时没有任何警告或错误)。在 IntelliJ IDEA 中,使用 javac 和 Eclipse 编译器都会出现问题。

【问题讨论】:

  • 您是否正在展示您已经证明是重现错误的最小设置?这里有很多接口,如果不能用更少的东西来演示,那么问题看起来很复杂。
  • 反编译在本地环境中运行时执行的MutableSet.class。那里有默认方法吗?
  • @DraganBozanovic,是的,所有超接口$plus 方法都有桥接方法。不过,ArraySet 类中没有桥接方法。
  • “Netbeans with jdk1.8.0_65”没有复制
  • 你的项目结构是什么?您在其中进行断言的代码是否与MutableSet 在同一个jar 中?

标签: java interface abstract-methods default-method java-bridge-method


【解决方案1】:

(根据上面作者的评论做出答案:问题已解决):

进行全面清理和重建也解决了这个问题。

尽管如此,在某些时候肯定存在导致错误二进制文件的错误。

【讨论】:

    猜你喜欢
    • 2013-07-11
    • 2021-02-07
    • 2019-03-17
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多