Я читал "Java. Руководство для начинающих" Герберта Шильдта. В разделе об общих интерфейсах на одной странице автор пишет (выделено мной):
Any class that implements a generic interface must itself be generic.
И на следующей странице (выделено мной):
In general, if a class implements a generic interface, then that class must also be generic, at least to the extent that it takes a type parameter that is passed to the interface.
Итак, существуют ли какие-либо конкретные ситуации, когда неуниверсальный класс может реализовать универсальный интерфейс в Java? Или все такие классы являются универсальными в том смысле, что они «наследуют» эту общность от универсального интерфейса?
УПД: Мне нужно было прочитать этот раздел дальше. Далее автор заявляет:
Of course, if a class implements a specific type of generic interface, such as shown here:
class MyClass implements Containment<Double> {then the implementing class does not need to be generic.
Это, я считаю, суть всех ответов на мой пост.




Можно создать неуниверсальный класс, реализующий универсальный интерфейс, при условии, что предоставлены параметры типа.
Относительно простой пример:
public class LocalDateParser implements Function<String, LocalDate> {
public LocalDate apply (String s) {
return LocalDate.parse(s);
}
}
Конечно, вы можете назначить экземпляр этого класса только Function<String, LocalDate>, а не любому другому Function<T, R>.
Каждый раз, когда класс или интерфейс поставляется с параметрами типа, они должны быть предоставлены. В противном случае это просто приводит к боли. Соответствующий вопрос: Что такое необработанный тип и почему мы не должны его использовать?
Я думаю, что автор явно не прав в обоих утверждениях. Универсальный класс — это класс, который принимает параметр универсального типа. И вы можете создать класс, который не принимает никаких параметров универсального типа, реализующих универсальный интерфейс:
public class CaseInsensitiveComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
}
In fact, this class already exists in the JDK, though it's implemented differently. Please see String.CASE_INSENSITIVE_ORDER for further details.
Я думаю, именно это имел в виду Джо С. Я должен был прочитать раздел дальше. Далее автор заявляет: «Конечно, если класс реализует определенный тип универсального интерфейса, [...] тогда реализующий класс не обязательно должен быть универсальным». Так что я считаю, что это вопрос семантики.
@JohnAllison "должен сам по себе должен быть универсальным" - это не просто плохая семантика. Это не правильно! Существует больше случаев, когда неуниверсальные классы реализуют универсальный интерфейс, чем универсальные классы, реализующие универсальные интерфейсы с использованием одних и тех же аргументов.
Руководство, которое вы читаете, неверно.
Существует множество примеров необобщенных классов, реализующих обобщенные интерфейсы.
Самый распространенный — Comparable<T>. В javadoc Java 8 перечислены 152 реализующих класса, некоторые из которых передают в интерфейс аргумент универсального типа, поскольку все они должны указывать себя в качестве аргумента для Comparable, например.
public final class String implements Serializable, Comparable<String>, CharSequence
public final class Integer extends Number implements Comparable<Integer>
public final class Instant implements Temporal, TemporalAdjuster, Comparable<Instant>, Serializable
Итак, когда реализуется определенный тип универсального интерфейса, реализующий класс не обязательно должен быть универсальным - хорошо. Но если в объявлении интерфейса используется параметр типа, то класс, реализующий интерфейс, также должен указать его, верно?