Как преобразовать класс java.lang.Class <Mapper>в класс java.lang.class <TableMapper> - PullRequest
1 голос
/ 23 сентября 2011

Смотрите решение внизу.

Я пытаюсь написать некоторый общий код обработки, но в 1 из подклассов требуется более специфичный класс.

Итак, базовый класс как поле типа Class, и в подклассе я пытаюсь привести этот объект Class к типу Class, который является подклассом org. Apache. Hadoop. Hbase. Mapreduce.Mapper. .

Я получаю следующую ошибку от Netbeans:

"Incompatible types
required: java.lang.Class<org.apache.hadoop.hbase.mapreduce.TableMapper>
found: java.lang.class<capture#3 of ? extends org.apache.hadoop.mapreduce.Mapper>"

когда я пытаюсь следующий код

Class<TableMapper> tableMapperClass = null;
if( mapperClass.equals(TableMapper.class) ) {
    tableMapperClass = TableMapper.class.asSubclass(mapperClass);

    //do stuff
}

и я получаю:

incompatible types
required: java.lang.Class<org.apache.hadoop.hbase.mapreduce.TableMapper>
found: java.lang.Class<capture#8 of ? extends org.apache.hadoop.hbase.mapreduce.TableMapper>

для

Class<TableMapper> tableMapperClass = null;
if( mapperClass.equals(TableMapper.class) ) {
    tableMapperClass = mapperClass.asSubclass(TableMapper.class);

    //do stuff
}

Хорошо, получил ответ от моего сотрудника, похоже, это должно работать:

Class<? extends TableMapper> tableMapperClass = null;
if( mapperClass.equals(TableMapper.class) ) {
    tableMapperClass = mapperClass.asSubclass(TableMapper.class);

    //do stuff
}

1 Ответ

2 голосов
/ 23 сентября 2011

Если вы хотите назначить класс для tableMapperClass , который на самом деле является подклассом TableMapper, вам необходимо изменить тип переменной. Вместо этого используйте:

Class<? extends TableMapper> tableMapperClass = null;

и теперь вы можете назначить TableMapper.class или любой подкласс этой переменной. Когда вы пишете Class<TableMapper>, вы обещаете, что переменная будет точно TableMapper.class или null.

Другой пример:

Class<Number> number = Integer.class; // does not compile
Number number = new Integer(1); // compiles fine
Class<? extends Number> number = Integer.class; // also ok

Обратите внимание, что вы можете делать разные вещи с помощью Class<Number>, тогда как вы можете Class<? extends Number>. Например, вы можете вызвать конструктор Class<Number>, потому что вы знаете класс. Вы не можете сделать это с Class<? extends Number>, потому что конструкторы не определены во время компиляции.

Аналогично, скажем, List<Number> против List<? extends Number>. Вы можете вызвать list.add (7) для переменной типа List<Number>, но вы не можете сделать это для List<? extends Number>, потому что вы не знаете тип второго списка. Например, это может быть List<Double>, в этом случае добавление целого числа не допускается.

Дженерики странные. :) Надеюсь, это поможет.

...