Расхождения в компиляторе javac - PullRequest
4 голосов
/ 25 января 2012

Обновление: похоже, что это связано с Eclipse, а не с Гудзоном, поэтому я соответствующим образом обновил вопрос.

При запуске Maven по команде я получаю некоторые ошибки компиляторалиния, но у всех разработчиков в нашей группе есть код, работающий нормально в Eclipse (некоторые общие сложности, подробности см. ниже).Как это может отличаться и что с этим делать?

Неудачный код выглядит следующим образом:

299 private <T extends ProductClassDTO> List<T> convertProductClass(List<? extends ProductClassDTO> fromList) {
300     List<T> toList = new ArrayList<T>();
301     for (ProductClassDTO from : fromList) {
302         T to = convert(from);
303         toList.add(to);
304     }
305     return toList;
306 }

Это ошибка на сервере сборки:

[ERROR] ...java:[302,26] type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,com.volvo.protom.util.dto.ProductClassDTO

(Я знаю, что в SO есть другие вопросы + ответы на этот вопрос, но они, похоже, не относятся к этому конкретному вопросу, поскольку изменение на T to = <T>convert(from) не работает, возможно, мне следует заняться чем-то другим?) ЯПредположение об ошибке означает, что в этом классе есть несколько convert методов и более одного соответствия?

Спасибо!

Обновление 2: Это преобразованиеподписи:

private void convert(TestObjectDTO from, TestObjectDTO to);
private <T extends TestObjectDTO> T convert(TestObjectDTO from);
private void convert(ProductClassDTO from, ProductClassDTO to);
private <T extends ProductClassDTO> T convert(ProductClassDTO from);
private void convert(TestObjectTypeDTO from, TestObjectTypeDTO to);
private <T extends TestObjectTypeDTO> T convert(TestObjectTypeDTO from);

Ответы [ 2 ]

0 голосов
/ 06 сентября 2012

Eclipse и JDK javac немного отличаются, см. Комментарий @ maximdim .Всегда запускайте из командной строки, чтобы обеспечить совместимость (хотя Javac в Eclipse кажется более правильным).

0 голосов
/ 25 января 2012

Полагаю, подписи этих методов не такие, какими они должны быть. Универсальные методы, в которых универсальный параметр встречается only в типе возвращаемого значения (как в <T extends ProductClassDTO> T convert(ProductClassDTO)), обычно не то, что вам нужно.

Это означает, что для вызывающего абонента допустимо вызывать метод и приводить результат к любому возможному подтипу ProductClassDTO. Обычно существует только одно возможное значение, которое удовлетворяет этому требованию: null. Таким образом, методы преобразования всегда должны возвращать null, чтобы быть безопасными для типов. В противном случае ClassCastException s может возникнуть в коде вызова.

Помните, что из-за стирания типов методы convert не имеют возможности узнать, какой тип запрашивает вызывающий объект T, поэтому они не могут возвращать экземпляры разных типов в соответствии со значением T .

Та же проблема возникает для метода convertProductClass, хотя здесь все не так плохо. Этот метод необходим для возврата списка, который содержит только такие значения, которые вызывающая сторона может интерпретировать как любой подтип ProductClassDTO. Единственными значениями, которые это удовлетворяют, являются null, пустой список и списки, содержащие только null значений. Все остальные случаи могут привести к ClassCastException где-то при использовании списка.

Что вы можете сделать:

  • Если методы преобразования возвращают всегда один и тот же тип, измените возвращаемое значение тип методов к этому типу.
  • Если вызывающие не заботятся о конкретном типе, а просто должны знать, что это подтип ProductClassDTO, измените типы возвращаемых значений на ProductClassDTO и List<ProductClassDTO> соответственно.
  • Если методы convert должны возвращать экземпляры типов в соответствии с желанием вызывающей стороны, вам нужно явно указать им тип возвращаемого типа, передав экземпляр Class<T> в качестве дополнительного параметра всем этим методам. Затем методы convert могут использовать этот объект для создания новых экземпляров соответствующих типов.
...