2012-02-29 5 views
13

Как-то мой старый вопрос был закрыт, поэтому я открываю новый:Как избежать непроверенных предупреждений броска с Java дженерик

Я использую Java Generics для реализации универсальной двунаправленного Hash Карты из SQL-запрос. Он должен иметь возможность отображать любую комбинацию пар String, Integer взад и вперед. Следует использовать так:

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); 

Конечно, это должно быть возможно создать вечера (Integer, Integer) и так далее ...

Моя реализация Пика Карта выглядит следующим образом (без добытчик ...):

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; 
    } 
} 

у меня нет ошибок компилятора, и я уверен, что он будет работать таким образом. НО Я получаю непроверенные предупреждения о методах «getInstance». Когда я бросаю Extractor (E) в Extractor (L) ...

Как я должен правильно нарисовать? Или что мне не хватает? Или я должен просто подавлять эти предупреждения?

ответ

24

Вы получаете предупреждения, потому что то, что вы делаете, не может быть доказано в безопасности. Вы принимаете при условии, что, что getInstance(colTypeL) вернет Extractor<L> - но это не может быть проверено ни во время компиляции, ни во время выполнения.

Вы можете использовать @SuppressWarnings("unchecked"), как упоминалось другими, но я попытался бы переосмыслить дизайн несколько.

+0

Да, я понимаю вашу точку зрения. Я хотел бы использовать общий тип L для инициализации моего Extractor. Поэтому вместо того, чтобы давать «colType» в методе getInstance, я хотел бы сделать что-то вроде getInstance (L) и getInstance (R) ... Это возможно? Я ненавижу тревожные предупреждения! – Sauer

+1

@Sauer: Вы должны знать 'L' и' R' во время выполнения, что обычно означает наличие параметров конструктора типа 'Class ' и 'Class ' или что-то подобное. –

+8

Одна из возможностей заключается в том, чтобы конструктор взял необходимые экстракторы: 'PickMap (String sql, Extractor leftExtractor, Extractor rightExtractor>)'. Это не только делает сборку безопасной, но и позволяет кому-то еще прийти и решить, что они хотят «PickMap », не изменяя код «PickMap» (предполагая, что «Extractor» - это интерфейс или класс, к которым у них есть доступ к). – yshavit

5

Вы можете использовать следующую аннотацию, чтобы компилятор не вывод этих предупреждений:

@SuppressWarnings("unchecked") 

Смотрите эту related question, которая занимается тем же вопросом. Ответ там объяснит все, что вам нужно знать.