2012-02-29 13 views
13

Jakoś moje stare pytanie zostało zamknięte, więc otwieram nowy:Jak uniknąć niesprawdzony ostrzeżeń odlewanych z Java rodzajowych

używam Java Generics zaimplementować rodzajowe dwukierunkowy Hash Mapa z kwerendy SQL. Powinien być w stanie odwzorować dowolną kombinację ciągów, liczb całkowitych w tę iz powrotem. Powinien być stosowany tak:

String sql = "SELECT string_val, int_val FROM map_table"; 
PickMap<String, Integer> pm1 = new PickMap<String, Integer>(sql); 

String key1 = "seven"; 
Integer value1 = pm1.getLeft2Right(key1); 

Integer key2 = 7; 
String value2 = pm1.getRightToLeft(key2); 

Oczywiście powinno być możliwe, aby stworzyć pm (Integer, Integer) i tak dalej ...

Moja implementacja Picka Mapa wygląda następująco (bez getter ...):

public class PickMap<L, R> { 

    private final HashMap<L, R> left2Right = new HashMap<L, R>(); 
    private final HashMap<R, L> right2Left = new HashMap<R, L>(); 

    public PickMap(String sql) throws OException { 
     DTable d = new DTable(sql); 
     int colTypeL = d.t.getColType(1); 
     int colTypeR = d.t.getColType(2); 
     Extractor<L> extLeft = (Extractor<L>) getInstance(colTypeL); 
     Extractor<R> extRight = (Extractor<R>) getInstance(colTypeR);  
     int numRows = d.t.getNumRows(); 
     for(int i=1;i<=numRows;i++) { 
      L leftVal = extLeft.extract(d, i); 
      R rightVal = extRight.extract(d, i); 
      this.left2Right.put(leftVal, rightVal); 
      this.right2Left.put(rightVal, leftVal); 
     } 
    } 

    private Extractor<?> getInstance(int type) { 
     if(type == 1) 
      return new IntExtractor(); 
     else 
      return new StringExtractor(); 
    } 
} 

interface Extractor<E> { 
    E extract(DTable source, int row); 
} 

class IntExtractor implements Extractor<Integer> { 

    @Override 
    public Integer extract(DTable source, int row) { 
     int value = 5; 
     return new Integer(value); 
    } 
} 

class StringExtractor implements Extractor<String> { 

    @Override 
    public String extract(DTable source, int row) { 
     String retVal = "hello"; 
     return retVal; 
    } 
} 

Nie mam błędów kompilatora i jestem prawie pewien, że to zadziała w ten sposób. ALE otrzymuję niezaznaczone rzucane ostrzeżenia na temat metod "getInstance" Gdzie odleję ekstraktor (E) do ekstraktora (L) ...

Jak powinienem rzucać poprawnie? Albo czego mi brakuje? Czy powinienem po prostu stłumić te ostrzeżenia?

Odpowiedz

24

Otrzymujesz ostrzeżenia, ponieważ to, co robisz, nie może być udowodnione jako bezpieczne. Jesteś przy założeniu, że że getInstance(colTypeL) zwróci Extractor<L> - ale to nie może być zweryfikowane w czasie kompilacji lub czasu wykonania.

Możesz użyć @SuppressWarnings("unchecked"), jak wspomniano przez innych, ale spróbuję nieco przemyślenia projektu.

+0

Tak, tak, rozumiem twój punkt widzenia. Chciałbym użyć typowego L do wprowadzenia mojego ekstraktora. Więc zamiast podawać "colType" w metodzie getInstance, chciałbym zrobić coś takiego jak getInstance (L) i getInstance (R) ... Czy to możliwe? Nienawidzę tłumiących ostrzeżeń! – Sauer

+1

@Sauer: Musiałbyś znać 'L' i' R' w czasie wykonywania, co zwykle oznacza posiadanie parametrów konstruktora typu 'Class ' i 'Class ' lub coś podobnego. –

+8

Jedną z możliwości jest, aby konstruktor wziął potrzebne ekstraktory: 'PickMap (String sql, Extractor leftExtractor, Extractor rightExtractor>)'. To nie tylko sprawia, że ​​kompilacja jest bezpieczna, ale także pozwala komuś wejść i decyduje się na "PickMap " bez konieczności zmiany kodu 'PickMap' (zakładając, że' Extractor' jest interfejsem lub klasą, do której ma dostęp do). – yshavit

5

Można użyć następującego adnotacji, aby nie kompilator wyjścia te ostrzeżenia:

@SuppressWarnings("unchecked") 

Zobacz ten related question która zajmuje się tym samym numerze. Odpowiedź tam wyjaśni wszystko, co musisz wiedzieć.

Powiązane problemy