#java #generics
#java #generics
Вопрос:
Итак, я хочу сделать это:
public interface IFieldObject {
public Comparable get();
}
public interface IFieldCondition {
public boolean apply(IFieldObject field, Comparable compare);
}
public class EqualTo implements IFieldCondition {
public boolean apply(IFieldObject field, Comparable compare) {
return (field.get().compareTo(compare) == 0);
}
}
но Eclipse выдает мне предупреждения:
Безопасность типа: Метод compareTo(Object) принадлежит к сопоставимому необработанному типу. Ссылки на сопоставимый универсальный тип должны быть параметризованы
Итак, я превратил это в:
public interface IFieldObject {
public Comparable<?> get();
}
public interface IFieldCondition {
public boolean apply(IFieldObject field, Comparable<?> compare);
}
public class EqualTo implements IFieldCondition {
public boolean apply(IFieldObject field, Comparable<?> compare) {
return (field.get().compareTo(compare) == 0);
}
}
который не компилируется из-за:
Метод compareTo(захват #1-оф ?) в сопоставимом типе не применим для аргументов (Comparable)
Каков правильный способ сделать это? (без предупреждений, следующих за идиоматическим Java >= 1.6)
Ответ №1:
В настоящее время у вас нет гарантии, что тип, возвращаемый field.get()
, действительно сопоставим с типом, указанным методом. В идеале, сделать все это универсальным, например:
public interface IFieldObject<T extends Comparable<T>> {
public T get();
}
public interface IFieldCondition<T> {
public boolean apply(IFieldObject<T> field, Comparable<T> compare);
}
public class EqualTo<T> implements IFieldCondition<T> {
public boolean apply(IFieldObject<T> field, Comparable<T> compare) {
return (field.get().compareTo(compare) == 0);
}
}
Вы, без сомнения, могли бы сделать это более общим, используя дополнительные захваты, но это отправная точка.
Комментарии:
1. Я хотел бы избежать дополнительных спецификаций для IFieldObject<T …> . Похоже, что версия Java «старой школы» просто «работает», и она более компактна, но я понимаю суть. Я действительно предпочел бы ошибку во время выполнения, чем всю эту типизацию 🙂
2. Один из способов, который я нахожу удобным для чтения универсальных методов, заключается в следующем: для всех типов T get() возвращает сопоставимый<T> .
3. чтобы сделать его еще лучше,
<T extends Comparable<? super T>>
, заставить его работать для подклассов сопоставимых типов
Ответ №2:
Как насчет этого?
public interface IFieldObject {
public<T> Comparable<T> get();
}
public interface IFieldCondition {
public boolean apply(IFieldObject field, Comparable<?> compare);
}
public class EqualTo implements IFieldCondition {
public boolean apply(IFieldObject field, Comparable<?> compare) {
return (field.get().compareTo(compare) == 0);
}
}
Комментарии:
1. выглядит хорошо! можете ли вы указать мне на ресурс, который объясняет разницу между «общедоступным сопоставимым<?> foo()» и «общедоступным <T> Сопоставимым<T> foo()»?
2. Проверьте Java generic methods