代码之家  ›  专栏  ›  技术社区  ›  Clashsoft

不同Java版本的奇怪默认方法行为

  •  10
  • Clashsoft  · 技术社区  · 9 年前

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

    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 bug,编译器未能添加所有必需的桥方法(代码编译时没有任何警告或错误)。在IntelliJ IDEA中,使用 javac语言 和Eclipse编译器。

    1 回复  |  直到 9 年前
        1
  •  0
  •   Andremoniy    9 年前

    (答案基于作者的上述评论:问题已解决):

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

    尽管如此,在某个点上,一定存在导致错误二进制文件的错误。