Почему компилятор java выдает предупреждение о необработанных типах для литерала класса?

Я использую mockito для написания некоторых тестов и использую следующий фрагмент кода:

ArgumentCaptor<LinkedList> captor = ArgumentCaptor.forClass(LinkedList.class); 

Это компилируется и работает нормально, за исключением предупреждения о том, что «captor» является необработанным типом, и я должен заменить его чем-то вроде:

ArgumentCaptor<LinkedList<String>> captor = ArgumentCaptor.forClass(LinkedList<String>.class);

Проблема в том, что LinkedList‹String›.class не существует, поэтому правая часть задания никогда не скомпилируется.

Предполагая, что подавление предупреждения неэстетично, есть ли элегантное решение? Если нет, то почему компилятор предупреждает меня о чем-то, что я не могу исправить?


person jwepurchase    schedule 21.12.2014    source источник
comment
ты пробовал LinkedList<?>?   -  person jtahlborn    schedule 21.12.2014
comment
Не думаю, что вы получите ответ, который вам понравится. Обобщения уже увеличили сложность языка в ошеломляющей степени (подстановочные знаки, ‹›, рекурсивные границы, которые никто не понимает, общие методы, новые значения extends и super и т. д. и т. д.), так что будьте благодарны, что это не стало еще хуже. Выполнение этой компиляции без предупреждения потребовало бы еще большего усложнения языка (в частности, LinkedList<String>.class нужно было бы сделать легальным кодом), поэтому в некотором смысле вы должны быть благодарны, что это не работает. Я думаю, вам просто нужно подавить предупреждение и забыть об этом.   -  person Paul Boddington    schedule 21.12.2014
comment
@pbabcdefp На самом деле в Mockito есть механизм, специально разработанный для решения проблем с дженериками. Вы просто аннотируете свои объявления, а затем просите Mockito создать все для вас.   -  person azurefrog    schedule 21.12.2014
comment
@azurefrog Спасибо. Я даже никогда не слышал о Mockito. Может ли он что-нибудь сделать с раздражающим общим предупреждением о создании массива, которое вы получаете, когда пытаетесь создать List<List<String>> с помощью Arrays.asList?   -  person Paul Boddington    schedule 21.12.2014
comment
возможный дубликат Mockito isA (Class‹T› clazz) Как разрешить тип безопасность?   -  person Joe    schedule 21.12.2014
comment
@Joe: Это как-то связано с Mockito, но я не считаю это дубликатом.   -  person Makoto    schedule 21.12.2014
comment
@Joe Я не думаю, что подход TypeToken здесь уместен, поскольку подход с аннотациями намного чище. В документах API Captor даже упоминается эта конкретная ситуация: одно из преимуществ использования аннотации @Captor заключается в том, что вы можете избежать предупреждений, связанных с захватом сложных универсальных типов.   -  person azurefrog    schedule 21.12.2014
comment
@azurefrog: на самом деле я не задавал фиктивный вопрос; это был просто пример последнего места, где это раздражение появилось для меня. В этом случае аннотация элегантно решает проблему, но означает ли это, что лучше избегать использования литерала класса в качестве параметра метода?   -  person jwepurchase    schedule 21.12.2014
comment
@pbabcdefp - мне нравится ответ, который мне не понравится. Если альтернативой является ужасный, чрезмерно сложный беспорядок, я могу с этим смириться.   -  person jwepurchase    schedule 21.12.2014


Ответы (1)


В Mockito есть аннотация @Captor, предназначенная для позволяют избежать подобных предупреждений.

Используя его, вам не нужно вручную new настраивать ArgumentCaptor. Вы можете просто объявить его с помощью аннотации, а затем вызвать MockitoAnnotations.initMocks(this); для "автоматического" создания захвата.

вместо этого:

ArgumentCaptor<LinkedList> captor = ArgumentCaptor.forClass(LinkedList.class); 

сделай это:

@Captor
ArgumentCaptor<LinkedList<String>> captor;

@Before
public void init() {
   // initialize fields annotated with Mockito annotations
   MockitoAnnotations.initMocks(this);  
}
person azurefrog    schedule 21.12.2014
comment
Теперь вы должны использовать @RunWith(MockitoJUnitRunner.class) или новый MockitoJunitRule вместо MockitoAnnoyions.initMocks(this), они безопаснее. Не говоря уже о том, что именование тоже лучше, дело не только в моках. - person Brice; 21.12.2014
comment
Спасибо за мокито совет. - person jwepurchase; 21.12.2014
comment
Я собираюсь принять этот ответ, потому что, хотя я на самом деле не задавал вопрос Mockito, он подсказал мне способ его решения. (Я отредактировал ответ, чтобы добавить ссылки на это решение). Но какое решение! Маловероятно, что если бы я писал код, я бы приложил все усилия, чтобы избавиться от предупреждения компилятора. - person jwepurchase; 21.12.2014