2008-10-27 10 views
14

mam rozszerzenie klasy zdefiniowanej w bibliotece, których nie mogę zmienić:Czy można pominąć niezaznaczone ostrzeżenia podczas przesłaniania metody parametrami typu surowego?

public class Parent 
{ 
    public void init(Map properties) { ... } 
} 

Jeśli jestem definiowania klasy „dziecko”, który rozciąga się rodzicem i używam Java 6 z rodzajowych, co jest najlepszym sposobem nadpisać metodę init bez uzyskiwania niezaznaczonych ostrzeżeń?

public class Child extends Parent 
{ 
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized 
    public void init(Map properties) { } 
} 

Jeśli dodać parametry rodzajowe, otrzymuję:

// error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it 
    public void init(Map<Object,Object>) { ... } 
    // same error 
    public void init(Map<? extends Object,? extends Object>) { ... } 
    // same error 
    public void init(Map<?,?>) { ... } 

Błąd ten występuje niezależnie od tego, czy mogę używać określonego typu, ograniczonego wieloznaczny, lub nieograniczony wieloznaczny. Czy istnieje poprawny lub idiomatyczny sposób nadpisania nie ogólnej metody bez ostrzeżeń i bez użycia @SuppressWarnings ("odznaczone")?

Odpowiedz

12

Tak, trzeba zadeklarować metodę nadrzędny z tym samym podpisem, jak w klasie nadrzędnej, bez dodawania żadnych informacji rodzajowych.

Myślę, że najlepiej jest dodaj adnotację @SuppressWarnings("unchecked") do parametru typu surowego, a nie do metody, aby nie blokować innych ostrzeżeń generycznych, które mogą występować we własnym kodzie.

+0

@SuppressWarnings jest zdecydowanie najlepszym wyborem. Jest do bani, ale tak się dzieje, gdy próbujesz zmusić generycznych do biblioteki, która ich nie używa. –

+0

'@SuppressWarnings (" rawtypes ")' powinno również wystarczyć. –

2

Krótka odpowiedź: nie można tego zrobić.

Niezadowalająca odpowiedź: wyłącz (specyficzne) ostrzeżenia w pliku IDE/build.xml.

Jeśli nie możesz zmienić biblioteki, niestety, musisz trzymać się nietypowych metod.

Problem polega na tym, że pomimo usunięcia wymazu oba init() mają tę samą sygnaturę, w rzeczywistości mogą być to różne metody - lub takie same (*). Kompilator nie może stwierdzić, czy ma on nadpisywać czy przeciążać, więc jest zabroniony.

(*) Załóżmy, że programista biblioteki miał na myśli init (Map < String, Integer >). Teraz wdrażasz init (Map < String, String >). To przeciąża i powinny istnieć dwie metody w vtable klasy Child.

Ale co, jeśli programista biblioteki oznaczał init (Map < String, String >)? Wtedy jest to nadrzędne, a twoja metoda powinna zastąpić oryginalny init w klasie Child i powinna istnieć tylko jedna metoda w vtable Child.

P.S. Nienawidzę jak rodzajowych wdrożone w Javie :-(

+0

Czy możesz wyjaśnić, dlaczego metody z tym samym (wymazanym) podpisem mogą być różnymi metodami kompilatora? Kompilator nie wie, co programista ma na myśli podczas kodowania ... ;-) – nrainer

0

Musisz zadeklarować metodę z tym samym podpisem co rodzic, i dlatego otrzymasz ostrzeżenia podczas kompilacji. Możesz je wyłączyć za pomocą @SuppressWarnings ("niezaznaczone")

Powodem, dla którego nie ma sposobu, aby się tego pozbyć, są ostrzeżenia, które informują, że można utworzyć kolekcje zawierające nieprawidłowe typy. Ostrzeżenia powinny zniknąć, gdy usunięty zostanie cały kod, który na to zezwala. Ponieważ dziedziczysz z klasy nietypowej, zawsze będzie można utworzyć kolekcję z nieprawidłową zawartością.

2

Myślę, że powyższa odpowiedź oznaczała zamiast tego @SuppressWarnings ("rawtypes").

Powiązane problemy