2014-10-21 26 views
13

Masz interesującą sytuację po wydaniu wersji Java 1.8.0_25 w dziczy ... Wierzę, że źródłem mojego problemu jest związane głównie z nowymi (do 1.8) cechami "domyślnych" implementacji w ramach interfejsów.Java 8: Spliterator, Iterator, Collection i "domyślne" implementacje w interfejsach (zduplikowane metody o nazwie spliterator)

Aplikacja, nad którą pracuję, jest obecnie ukierunkowana na 1,7, która do tej pory działała dobrze. Dopóki użytkownicy nie zaczną aktualizować do wersji 1.8. Teraz, gdy nasi użytkownicy zaczęli aktualizować się do wersji 1.8, nasza ręka jest nieco zmuszona do przejścia na wsparcie 1.8.

Naprawiliśmy większość problemów (głównie związanych ze zmianami pakietów JavaFX między 1.7 a 1.8), ale pozostał jeszcze jeden problem dezorientujący.

W mojej mądrości, lub jej brak, ja, jakiś czas temu, postanowiliśmy stworzyć SortedList <T> która rozciąga się od AbstractList <T>. Do tej pory, ta klasa pracował w porządku, jednak po uruchomieniu na 1,8 starcie, otrzymuję:

Duplicate methods named spliterator with the parameters() and() are inherited 
from the types Collection<T> and Iterable<T> 

To dla mnie wydaje się być spowodowane przez „default” implementacji niektórych interfejsów, które są realizowane przez Klasa abstrakcyjna <T> (moja klasa sortowane <T> klasa nie implementuje żadnych dodatkowych interfejsów innych niż Serializable). Implementowanie Serializable jest dla nas kolejnym problemem, ponieważ musimy wspierać deserializację obiektów SortedList <T>, nie ma możliwości obejścia tego!).

Mogę pozbyć się błędu, zapewniając zastąpienie implementacji spliteratora() w mojej klasie SortedList <T>. Jednakże, jeśli jest zbudowany, nie działa już w środowisku Java 1.7. Jeśli będę próbować używać SortedList <T> z 1,7 starcie, otrzymuję:

Problem: 
Error: Unresolved compilation problems: 
The import java.util.Spliterator cannot be resolved 
Spliterator cannot be resolved to a type 

com.xxxx.xxxx.util.SortedList.<init>(SortedList.java:13) 

Ten błąd jest dość oczywiste, ponieważ mamy teraz przesłonięte metody spliterator() w SortedList <T> musi zawierać java.util.Spliterator, ale nie istnieje w wersji 1.7.

Idealnie nie chcielibyśmy, aby nasi klienci aktualizowali środowisko Java 1.8, jeśli tego nie chcą.

Czy nasza ręka jest tu zmuszana? Czy musimy zmusić użytkowników do aktualizacji do wersji 1.8, a także wprowadzenia nowej wersji dla wszystkich użytkowników, którzy sami zaktualizowali ją do wersji 1.8?

Czy ktoś wie, jak obejść ten problem?

W bardziej filozoficznej nucie, dlaczego interfejs został uszkodzony przy implementacji :-(. Może to być całkiem nowa funkcja, ale naprawdę powinna była unikać robienia wszystkiego, co mogłoby spowodować łamanie zmian w istniejącym kodzie, szczególnie w coś tak fundamentalnego jak listy/kolekcje itp.

Każda pomoc lub sugestie dotyczące tej sytuacji będą bardzo mile widziane.

Cheers,

Mark

+3

Ponieważ 'Collection ' * rozciąga * 'iterowalny ' nie powinno nigdy być takim „duplikat metody” błąd . To wskaźnik dla uszkodzonego kompilatora. Należy pamiętać, że [potrzebujesz kompilatora obsługującego środowisko Java 8 podczas używania klas Java 8, nawet jeśli nie korzystasz z poziomu źródłowego/docelowego Java 8] (http://stackoverflow.com/a/26105217/2711488). – Holger

+0

Hmm, myślałem, że wszystko, co zostało załatwione, trzeba będzie potrójnie sprawdzić i spróbować ponownie. Dzieki za sugestie. – Gumbatron

Odpowiedz

2

Ok, więc oboje (@Holger i @assylias) były prawidłowe ... Ale nasza sytuacja jest nieco bardziej skomplikowana.

Środowisko, w którym pracujemy, to Eclipse 3.8.1, który nie obsługuje języka Java 8 (i nie będzie w przyszłości dostępny dla mojej wiedzy). Więc nie możemy po prostu zmienić na kompilator Java 8 , aby naprawić problemy.

Nasz produkt to spora aplikacja Eclipse RCP. Aktualizacja naszego IDE nie jest obecnie opcją, ponieważ wymagałoby to dużych zmian. Będziemy musieli kontynuować , aby rozwijać się w środowisku Java 1.7 z tego powodu.

Jeśli ktoś jest zainteresowany, mamy rozwiązany przez:

  • Tworzenie fragmentów (po jednym w wersji Java, który powoduje problemy, więc trzy w naszym przypadku) dla naszego głównego wtyczki. Fragmenty te są skonfigurowane jako fragmenty łatek.
  • Dodano JAR FX Javy do fragmentów (Dokonano tego w celu rozwiązania niektórych problemów z Javą FX w poprzedniej wersji i ponownie w wydaniu 1.8.0_25).
  • Również w fragmentach, w tej samej przestrzeni nazw co główna wtyczka, dodaliśmy implementację klasy SortedList. Kod jest identyczny dla każdego przypadku, ale fragment dla Java 8 jest kompilowany specjalnie z kompilatorem Java 8. Zastąpienie metody spliterator() nie było konieczne na końcu (gdy skompilowano ją z kompilatorem Java 8 , działa dobrze i nadal kompiluje się z kompilatorem 1.7, ponieważ nie ma już odwołania do klasy Spliterator).

Prawdopodobnie nie jest to idealne rozwiązanie, ale zadziała, jak sądzimy :-).

Dzięki za twoje uwagi & sugestie, doceniamy.

2

Istotą metody jest domyślne, aby uniknąć sytuacji pan opisać. Poniższy kod kompiluje się i działa zgodnie z oczekiwaniami z Java 7 i 8:

public class SortedList<T> extends AbstractList<T> implements Serializable { 
    @Override public T get(int index) { return null; } 
    @Override public int size() { return 0; } 

    public static void main(String[] args) { 
    SortedList<String> s = new SortedList<>(); 
    System.out.println(s.size()); 
    } 
} 
+0

Tak właśnie bym chciał. Może być problem z kompilatorem, jak zasugerowano powyżej. – Gumbatron

0

spróbuj utworzyć klasy abstrakcyjnej, który zastępuje spliterator() z preferowanym zachowaniem rozdzielczości IE

abstract class Java8_AbstractCollection<E> extends AbstractCollection<E> { 

    /* (non-Javadoc) 
    * @see java.util.Collection#spliterator() 
    */ 
    public Spliterator<E> spliterator() { 
     return (Spliterator<E>) super.spliterator(); 
    } 
}