I have an interface,
MyInterface
, that extends Comparable since I want to be able to sort lists of these objects:1 global interface MyInterface 2 extends Comparable {
All classes that implement
MyInterface
contain this code to implement thecompareTo
method:
(Unfortunately these classes are extending different superclasses, and multiple inheritance isn’t possible with Apex)1 global class SubClass1 2 extends SuperClass1 3 implements MyInterface 4 { 127 public Integer compareTo( Object OtherRecord ){ 128 MyInterface OtherMyInterface = (MyInterface) OtherRecord ; 129 if ( this.getTimestamp() > OtherMyInterface.getTimestamp() ) return 1; 130 if ( this.getTimestamp() < OtherMyInterface.getTimestamp() ) return -1; 131 else return 0 ; 132 }
A Visualforce controller is trying to sort the these MyInterface objects, but it is failing with a run-time exception:
System.ListException: One or more of the items in this list is not Comparable
61 /* 62 for (MyInterface s : MyList){ 63 System.debug( s instanceOf Comparable ); 64 } 65 */ 66 MyList.sort();
Attempts to uncomment lines 61-64 fail with a compile time exception:
Operation instanceof is always true since an instance of MyInterface is always an instance of System.Comparable
Does anyone out there have any ideas on what I’m missing here? How is it that one of the objects is not Comparable if all of them are instances of Comparable?
Answer
There’s a subtle bug involved here, which I was able to replicate with the following execute anonymous:
interface MyInt extends Comparable {
}
class SuperC implements MyInt {
public Integer compareTo(Object o) {
return 0;
}
}
class SubC extends SuperC {
}
SuperC[] items = new SuperC[0];
items.add(new SubC());
items.add(new SuperC());
items.sort();
You can fix this by adding Comparable to the sub-class:
interface MyInt extends Comparable {
}
class SuperC implements MyInt {
public Integer compareTo(Object o) {
return 0;
}
}
class SubC extends SuperC implements Comparable {
}
SuperC[] items = new SuperC[0];
items.add(new SubC());
items.add(new SuperC());
items.sort();
Note that SubC will still be considered to be a MyInt as well, so you can mix and match as you need to.
Note that, while you can’t extend from multiple classes, it’s legal to implement multiple interfaces:
class SubC extends SuperC implements MyInt, Comparable {
}
You can use this to work around the problem for now, but ideally we should have someone look into why Apex Code behaves this way to begin with.
Attribution
Source : Link , Question Author : martin , Answer Author : sfdcfox