3

I've been reading "Java. A Beginner's Guide" by Herbert Schildt. In the section on generic interfaces on one page the author writes (emphasis mine):

Any class that implements a generic interface must itself be generic.

And on the next page (emphasis mine):

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.

So are there any specific situations where a non-generic class can implement a generic interface in Java? Or all such classes are generic in that they 'inherit' that generality from the generic interface?

UPD: I should have read the section further. The author goes on to state:

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.

This is, I believe, the gist of all the answers to my post.

Islam Hassan
  • 673
  • 1
  • 10
  • 21
John Allison
  • 966
  • 1
  • 10
  • 30

3 Answers3

4

It is possible to create a non-generic class that implements a generic interface, provided that the type parameters are provided.

A relatively simplistic example:

public class LocalDateParser implements Function<String, LocalDate> {
    public LocalDate apply (String s) {
        return LocalDate.parse(s);
    }
}

Of course, you can only assign an instance of this class to Function<String, LocalDate>, and not to any other Function<T, R>.

Joe C
  • 15,324
  • 8
  • 38
  • 50
  • Ah, so when a specific type of generic interface is implemented, the implementing class needn't be generic - ok. But if a type parameter is used in the interface declaration, then the class implementing the interface should also state it, right? – John Allison Jan 22 '19 at 20:58
  • Any time a class or interface comes with type parameters, these should be provided. Otherwise, it just leads to pain. Relevant question: [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Joe C Jan 22 '19 at 21:10
2

I think the author is plain wrong in both statements. A generic class is a class that accepts a generic type parameter. And you can create a class that doesn't accept any generic type parameter that implements a generic interface:

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.

fps
  • 33,623
  • 8
  • 55
  • 110
  • 1
    I believe this is what Joe C. meant. I should have read the section further. The author goes on to state: "Of course, if a class implements a specific type of generic interface, [...] then the implementing  class does not need to be generic." So I believe it's a matter of semantic. – John Allison Jan 22 '19 at 21:12
  • 2
    @JohnAllison *"**must** itself be generic"* is not just bad semantics. It's wrong! There are more cases of non-generic classes implementing generic interface, than there are generic classes implementing generic interfaces using the same arguments. – Andreas Jan 22 '19 at 21:19
2

The guide you're reading is wrong.

There are many examples of non-generic classes implementing generic interfaces.

The most common one is Comparable<T>. The Java 8 javadoc lists 152 implementing classes, few of which pass on a generic type argument to the interface, since they are all supposed to specify themselves as the argument to Comparable, e.g.

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
Andreas
  • 154,647
  • 11
  • 152
  • 247