1

Ok, this is my problem simplified:

class Group<T extends Comparable<T>> implements Comparable<Group<T>> { private String id; public Group(String id) { this.id = id; } @Override public int compareTo(Group<T> o) { return id.compareTo(o.id); } } class InnerGroup extends Group<Integer> { public InnerGroup(String id) { super(id); } } class OuterGroup extends Group<InnerGroup> { public OuterGroup(String id) { super(id); } } 

This produces this error by the compiler:

Error:(20, 32) java: type argument InnerGroup is not within bounds of type-variable T 

In reference to OuterGroup trying to extend Group. ItelliJ Idea says it's because InnerGroup must implement Comparable, but it is already doing so by means of inheriting it from Group.

In fact, if I try to force InnerGroup to implement Comparable, then the compiler will complain because InnerGroup would have two implementations of Comparable, which is an implicit recognition that it already has the interface implemented despite the aforementioned complain of not having it.

Any ideas on how to get out of this conundrum?

Thanks a lot in advance.

9
  • 3
    Your Group has the type parameter T extends Comparable<T>. In OuterGroup, you're providing the type argument InnerGroup. Is InnerGroup a subtype of Comparable<InnerGroup>? Commented Mar 12, 2018 at 19:31
  • 1
    The question stands. Is InnerGroup a subtype of Comparable<InnerGroup>? Commented Mar 12, 2018 at 19:34
  • And please provide a minimal reproducible example and an exact error message. Commented Mar 12, 2018 at 19:35
  • Yep, I see, my edition was on Comparable<Group<T>>. InnerGroup is declared there, you see is a subtype of Group<Integer> and hence it should be a "subtype" of Comparable<Group<Integer>> by indirect means I guess. Commented Mar 12, 2018 at 19:35
  • 1
    Try Group<T extends Comparable<? super T>>. Commented Mar 12, 2018 at 20:01

2 Answers 2

1

The bound T extends Comparable<T> means Group can only be parameterized with a type comparable to itself. InnerGroup is not a valid type because it's only comparable with Group<Integer>. To accept a type that's comparable with some supertype, you can loosen the constraint to T extends Comparable<? super T>.

Sign up to request clarification or add additional context in comments.

1 Comment

This works at compilation time, nonetheless had some side effects. I think I have come with a better solution that express my intentions better. I'm going to publish it.
0

I think I've managed to solve this once and for all. The solution of @shmosel had some side effects when things got a bit more complex, and once I have managed to fully grasp it, I think it didn't express what I wanted precisely. This, however, should do it:

class Group<T extends Group<T, R>, R extends Comparable<R>> implements Comparable<T> { String id; public Group(String id) { this.id = id; } @Override public int compareTo(T o) { return id.compareTo(o.id); } } class InnerGroup extends Group<InnerGroup, Integer> { public InnerGroup(String id) { super(id); } } class OuterGroup extends Group<OuterGroup, InnerGroup> { public OuterGroup(String id) { super(id); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.