2013-06-08 12 views
8

używam rodzajowych w Javie, ale nie jest tak dobry jak myślałemKolekcja bezpieczniejsza od standardowej listy o typie ogólnym?

public static void add(List l, Object o) { 
    l.add(o); 
} 

public static void main(String[] args) throws Exception { 
    List<Integer> list = new ArrayList<Integer>(); 
    add(list, "1.23"); 
    add(list, 1.23); 
    System.out.println(list); 
} 

Wszystko to kompiluje i działa. Kiedy otrzymam wartość z list, zostanie zgłoszony wyjątek.

Czy to może być bezpieczniejsze w Javie 6?

+3

Dlaczego nie użyć metody 'list.add()'? Deklaracja metody 'add()' z ogólnym parametrem 'List '. – NINCOMPOOP

+0

Rozumiem, ale mam do czynienia z typem wymazania (stary kod) –

+0

@ KalamarObliwy: Ale to pozwoli ci zaoszczędzić na błędach podczas kompilacji, a tym samym zaoszczędzi z 'ClassCastExceptions' w czasie wykonywania. – NINCOMPOOP

Odpowiedz

14

Proponuję przy użyciu standardowego Collections:

List<Integer> checked = Collections.checkedList(list, Integer.class); 

potem po prostu pracować na checked. Zgłoszenie ClassCastException zostanie rzucone podczas wstawiania dowolnej niezgodnej instancji - wcześniej (a więc lepiej) niż poprzednio (tj. Podczas pobierania).

N.B. sprawdź komunikaty kompilatora, Założę się, że masz jakieś ostrzeżenia wydrukowane tam, wspominając niebezpieczny/niezaznaczony kod. Twój problem jest dokładnie tym, co kompilator próbuje ci powiedzieć. Jeśli sterujesz sygnaturą add, ustaw ją jako ogólną - zapewni to bezpieczeństwo podczas kompilacji.

public static <T> void add(List<T> list, T t) { 
    list.add(t); 
} 
+0

+1 dla sugestii 'Collections.checkedList()'. Jednak funkcja 'add()' powinna zezwalać na wstawianie podtypów zadeklarowanego typu, więc jeśli lista została zadeklarowana jako 'List ', kompilator pozwoliłby na dodanie czegokolwiek. Dlatego też 'List ' byłoby lepszym rozwiązaniem niż 'List '. –

+0

Jeśli OP planuje ** dodać tylko ** do "listy", to masz całkowitą rację. Myślałem bardziej ogólne. – emesx

+0

Metoda 'add()' powinna ogólnie * dodawać tylko * do listy;) ale w drugiej chwili myślę, że * myliłem się * :): ponieważ chodzi o kolekcję i element, element otrzyma "promowany" przez kompilator do super typu przezroczyście. To, co powiedziałem, dotyczy tylko dwóch typów generycznych: 'A ' i 'B ' ponieważ są one niezmienne. –

3

Nie sądzę. Jeśli ta statyczna metoda add() jest faktem (czymś, czego nie kontrolujesz), niewiele możesz zrobić, ponieważ generyczne Java są zaimplementowane, aby były zgodne z Javą < 5.0.

Jednakże, jeśli jesteś w stanie zmienić podpis metody add(), można po prostu wymusić sprawdzanie typu, dzięki czemu pojawiają się błędy kompilatora dla kodu w metodzie main():

public static <T> void add(List<? super T> list, T object) { 
    list.add(object) 
} 
Powiązane problemy