I have a set of classes that all share some common attributes, so I made them all extend a common base class, BaseEntity. So I have, for example Foo extends BaseEntity and Bar extends BaseEntity.
I also want lists of these Foo and Bar objects to be sortable, so I have implemented Comparable. I have the classes defined as Foo extends BaseEntity implements Comparable and Bar extends BaseEntity implements Comparable, and sorting of lists of Foos or Bars works as expected - and, of course, the details of the sorting are different in the different subclasses. But I can't work out how to make my sorting work when I don't know in advance whether I'll have Foos or Bars. This code, for example, fails to compile:
public class UtilityClass {
...bunch of stuff...
List values;
public List sort() {
Collections.sort(values);
return values;
}
...more methods...
}
with the error message Bound mismatch: The generic method sort(List) of type Collections is not applicable for the arguments (List). The inferred type T is not a valid substitute for the bounded parameter >
I think the problem is that I am attempting to sort a list of BaseEntity objects, and BaseEntity itself doesn't implement Comparable. But now I face a problem: the only sensible thing to make BaseEntity objects comparable to is other BaseEntity objects, but when I add implements Comparable to BaseEntity, the compiler tells me that I've got problems now because my Foo class is trying to implement both Comparable and Comparable, which evidently is not allowed.
I know I could sidestep this issue by dropping the implements Comparable and just implementing Comparable, but then my compareTo methods will have to do ugly casting, and I thought that was exactly the sort of problem using generics was supposed to avoid.
What I really want to do is specify in the signature of BaseEntity that all its subclasses will be Comparable, but only to instances of the same subclass.
Any assistance gratefully received. Thanks!
解决方案
Use an intersection type, like this:
public class MyList> {...}
That specifies that T must be both a BaseEntity and Comparable to itself.