在通用超类中实现Comparable <T>

Alv*_*son 0 java generics

我有一个抽象的通用超类,我扩展它来制作具有特定类型ID的具体类:

public abstract class AbstractEntity<I> {
  ...
  private I id;
  private String name;
  ...
}
Run Code Online (Sandbox Code Playgroud)

我创建这样的具体类:

public class User extends AbstractEntity<Long> {...}
Run Code Online (Sandbox Code Playgroud)

现在我想使具体类与其他自己的实例相比(没有其他类型 - 这应该在编译时强制执行).默认情况下,该compareTo方法应该按名称排序,因此我想将其添加到超类中以避免重复代码.我想出来的唯一方法是使用这个丑陋的构造:

public abstract class AbstractEntity<I,T> implements Comparable<AbstractEntity<I,T>> {
  ...
  private I id;
  private String name;
  ...
  @Override
  public int compareTo(AbstractEntity<I,T> o) {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

...

public class User extends AbstractEntity<Long,User> {...}
Run Code Online (Sandbox Code Playgroud)

我认为这很难看,因为现在为了扩展超类,你需要再次重复具体的类名作为自身的类型参数,这是奇怪的和违反直觉的.是否有一种更优雅的方式来完成我所缺少的同样的事情?

谢谢!

Pau*_*ora 7

您正在寻找的是"自我类型",但这在Java中是无法实现的.你最接近的是使用一个递归绑定的类型参数,该参数应该是自我类型:

public abstract class AbstractEntity<I, E extends AbstractEntity<I, E>> implements Comparable<E> {
    ...
    private I id;
    private String name;
    ...
    public final String getName() {
        return name;
    }
    ...
    @Override
    public int compareTo(E otherEntity) {
        final String otherName = otherEntity.getName();
        ...
    }
}

public final class User extends AbstractEntity<Long, User> { }
Run Code Online (Sandbox Code Playgroud)

我建议不要使用这种模式,因为它令人困惑,很容易被滥用.例如:

public final class EvilUser extends AbstractEntity<Long, AnotherUser> { }
Run Code Online (Sandbox Code Playgroud)

我的建议:坚持以Comparable个体为基础实施.