Lassen Sie uns sagen, dass ich die folgende Klassenhierarchie:Seltsam Standardmethode Verhalten mit verschiedenen Java-Versionen
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
}
Wie Sie sehen können, nur die MutableSet
-Klasse stellt eine Implementierung für die $plus
Methode. In einem Testfall rufe ich diese Methode für eine Instanz des Typs ArraySet
auf. Der Test wird immer in der CI-Umgebung übergeben, während er immer mit einem AbstractMethodError
auf meiner lokalen Umgebung fehlschlägt. In beiden Fällen verwende ich Gradle (2.7).
Der Fehler:
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
Ausgabe:
CI (wo es funktioniert):
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)
Local (wo es nicht):
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)
Ich erwarte dies eine Art javac
zu sein Fehler, bei dem der Compiler nicht alle erforderlichen Bridge-Methoden hinzufügen kann (der Code wird ohne Warnungen kompiliert oder e Richtig). In IntelliJ IDEA tritt das Problem sowohl unter Verwendung von javac
als auch des Eclipse-Compilers auf.
Präsentieren Sie, was Sie bereits als das minimale Setup bewiesen haben, um den Fehler zu reproduzieren? Es gibt viele Schnittstellen hier, wenn es nicht mit weniger gezeigt werden kann, sieht das Problem ziemlich komplex aus. –
Dekompilieren Sie die 'MutableSet.class', die zur Laufzeit in Ihrer lokalen Umgebung ausgeführt wird. Gibt es dort eine Standardmethode? –
@DraganBozanovic, ja, es gibt Bridge-Methoden für alle Super-Interface '$ plus' Methoden. In der Klasse 'ArraySet' gibt es jedoch keine Bridge-Methoden. – Clashsoft