Java 1.4 to Java 1.5 - переписать код и избежать @SuppressWarnings - PullRequest
2 голосов
/ 04 августа 2010

У меня есть старый личный проект, написанный на Java 1.4, который я портирую на версию 1.5 (в которой я все еще новичок) для версии 2. Помимо добавления новых функций и рефакторинга кода, я также мигрирую в общие коллекции,аннотации и т. д.

Существует определенный фрагмент кода, который я не знаю, как изменить на 1.5, и не хочу добавлять на него @SuppressWarnings.Это выглядит так:

if (value instanceof Comparable) {
  isMatch = (((Comparable) value).compareTo(selectedValue) == 0);
} else {
  //fallback to equals
  isMatch = selectedValue.equals(value);
}

Это просто простое сравнение с расширенным соответствием в CompareTo () или по умолчанию равным равному (), если не тип Comparable.

Я получаюa: Comparable is a raw type. References to generic type Comparable<T> should be parameterized предупреждение.

Как изменить вышеприведенный код на 1.5 и снять предупреждение.Или нет другого выбора, кроме как добавить @SuppressWarnings?

Ответы [ 6 ]

2 голосов
/ 05 августа 2010

В частности, вы получаете предупреждение, потому что вам нужно квалифицировать Comparable с аргументом типа в приведении.Так что у вас есть ((Comparable<Type>)value), где Type - это (базовый тип) тип selectedValue.

Однако, даже если вы сделаете это, вы все равно получите предупреждение.На этот раз проблема в том, что <Type> «уходит» при компиляции, что означает, что нет никакого способа гарантировать, что класс действительно Comparable<Type>.Вы можете только проверить, является ли объект Comparable.Рассмотрим следующее тестовое приложение:

class Type{
  public int x = 0;
}

class Other implements Comparable {
  public int compareTo(Type obj) {
    return obj.x;
  }
}

class Test {
  public static void main(String[] args) {
    Other obj1 = new Other();
    Object value = obj1;
    String selectedValue = "";
    if (value instanceof Comparable) {
       System.out.println(((Comparable<String>) value).compareTo(selectedValue));
    }
  }
}

Код компилируется с предупреждением, поскольку, хотя value равно Comparable, его нельзя сравнивать с String с.Последнее все еще предпочтительнее, так как вы можете по крайней мере проверить, что аргумент имеет «ожидаемый» тип.

В конце вам понадобится @SuppressWarnings.

Обратите внимание, что еслиВы хотите, чтобы это работало с любым классом.Тогда вы можете также оставить все как есть (или использовать Comparable<Object>, поскольку они (в данном случае) эквивалентны).С добавлением @SuppressWarnings, очевидно.

1 голос
/ 05 августа 2010

Я бы переписал этот кусок кода следующим образом:

if (value instanceof Comparable<?>) { // <-- notice <?>
  // Declare local var and cast it here
  // You will incur warning, but it's localized to this one instance only
  //
  // Also not that this cast is safe as it matches the signature of Comparable
  // in Java 1.4
  @SuppressWarnings( "unchecked" )
  Comparable<Object> comp = (Comparable<Object>)value;

  // Now you can use compareTo
  isMatch = (comp.compareTo(selectedValue) == 0);
} else {
  //fallback to equals
  isMatch = selectedValue.equals(value);
}
1 голос
/ 05 августа 2010

Я не вижу способа написать этот код без предупреждения.Вам придется привести value к Comparable<? super Value>, что (поскольку оно указывает ограничение на параметр типа) является непроверенным приведением, что также приводит к предупреждению.

Я рекомендую подавить предупреждение, так каккод будет просто терпеть неудачу, даже если значение будет реализовывать Comparable с неподходящим параметром типа (обслуживает их правильно, если они реализуют Comparable, но не может сравниваться с экземплярами того же класса ...).

0 голосов
/ 04 августа 2010

Вы можете исправить предупреждение, просто убедившись, что класс значений расширяется.

class ClassOfValueUsingCompareTo implements Comparable{
       //class definition
}

Источник: http://forums.sun.com/thread.jspa?threadID=785803

Если вы сделаете это, вам, возможно, придется изменить логику, возможно, добавив больше абстракций на 1) Использование интерфейса для обеспечения полиморфизма.2) инкапсуляция операции isMatch в методе, который определен для полиморфных классов.

public interface ValueInterface{
      //interface definition
      public boolean isMatch();
}

class ClassOfValueUsingCompareTo implements ValueInterface,Comparable{
       //class definition
      public boolean isMatch(){
          //use compareto
       }
} 
class ClassOfValueUsingEquals  implements ValueInterface{
       //class definition
      public boolean isMatch(){
          //use equals
       }
}

Примечание: проблемы с использованием оператора instanceOf Избежание instanceof в Java

Надеюсь, что это отвечает на ваш вопрос.

0 голосов
/ 04 августа 2010

@ SuppressWarnings (2 шт.) Не очень хорошо работает в старой Java 5.0 (не было Java 1.5), однако, поскольку Java 5.0 уже почти год не используется, я предлагаю вам использовать Java 6, котораяне подавляет предупреждения немного лучше.

Важно понимать, что это всего лишь предупреждение.Даже библиотека Коллекций не может быть скомпилирована без предупреждений, и, похоже, разработчик не намерен всегда писать код, который не выдает вообще никаких предупреждений.

0 голосов
/ 04 августа 2010

Предупреждение связано с тем, что при использовании Comparable не используется универсальный тип.

Независимо от класса value вы захотите, чтобы этот класс реализовывал Comparable<Value>, где универсальный тип Value равен любому значению class. Тогда вы можете просто позвонить на номер value.compareTo(selectedValue) без необходимости набирать номер value instanceof Comparable.

...