Я хотел бы сделать следующее:
public class ImmutableList {
public ImmutableList add(U element) { ... }
}
То есть, учитывая неизменяемый список T
, вы можете добавить любой U
в список, чтобы получить неизменяемый список U
с ограничением, что U
должен быть супертипом T
. Например
Объектов
(при условии, что камни и гоминиды не имеют другого общего предка).В теории это звучит великолепно, но нижняя граница U
недопустима согласно JLS.Вместо этого я мог бы написать:
public class ImmutableList {
public ImmutableList add(T element) { ... }
public static ImmutableList add(ImmutableList extends U> list, U element) { ... }
}
Таким образом, компилятор правильно выведет наименьшую верхнюю границу между типом элемента списка и U
, который мы хотим добавить. Это законно. Это также отстой. Сравните:
// if 'U super T' were legal
list.add(monkey).add(human).add(rock);
// assuming 'import static ImmutableList.add'
add(add(add(list, monkey), human), rock);
Я большой поклонник функционального программирования, но я не хочу, чтобы мой Java-код выглядел как диалект Лиспа. Итак, у меня есть три вопроса:
WTF? Почему привязка не является законной? Этот вопрос на самом деле задавался здесь раньше ( «Почему параметр типа Java не может иметь нижнюю границу?» ), но я думаю, что вопрос в том виде, в котором он сформулирован, несколько запутан, и ответы там сводятся к до «это недостаточно полезно», что я не очень-то понимаю.
Раздел 4.5.1 JLSгласит: «В отличие от переменных обычного типа, объявленных в сигнатуре метода, при использовании подстановочного знака вывод типа не требуется. Следовательно, допустимо объявлять нижние границы подстановочного знака». Учитывая приведенную выше сигнатуру альтернативного метода static
, компилятор явно способен вывести наименьшую верхнюю границу, которая ему нужна, поэтому аргумент кажется неверным. Кто-то может возразить, что это не так?
Самое главное:Кто-нибудь может придумать законную альтернативу моей подписи метода с нижней границей? Вкратце цель состоит в том, чтобы код вызова выглядел как Java (list.add(monkey)
), а не как Lisp (add(list, monkey)
).