实现不安全的Java接口

inc*_*ate 6 inheritance scala language-interoperability

我最近在使用Spring Security进行开发时遇到了问题.它有一个GrantedAuthority带有以下签名的界面:

public interface GrantedAuthority extends Serializable, Comparable
Run Code Online (Sandbox Code Playgroud)

至于Java 1.5及更高版本,接口Comparable采用了一个类型参数T,在Spring Security库中省略了(显然,对于JVM 1.4兼容性).

所以我想GrantedAuthority在Scala中实现.

class Role extends GrantedAuthority {
  . . .
  def compareTo(obj: Any): Int = obj match {
    case (r: Role) => r.toString.compareTo(this.toString)
    case _ => -1
  }
}
Run Code Online (Sandbox Code Playgroud)

它不编译:

error: class Role needs to be abstract, since method compareTo in trait Comparable of type (T)Int is not defined
Run Code Online (Sandbox Code Playgroud)

如何在Scala中实现这样的接口?

ret*_*nym 4

Java 泛型的互操作问题(至少)有两种形式:

  1. 省略类型参数的 Java 代码(如您的示例中所示)会导致“原始类型”。Comparable被视为存在类型Comparable[_]。有时你可以想办法摆脱这个问题。但是,我没有看到在这种情况下实施的方法def compareTo(other: _) = ...
  2. Java 泛型没有声明位点差异的概念。要Comparable[T]使用逆变 scala 特征进行扩展Ordering[-T],除非您使用注释,否则将会发生错误@uncheckedVariance。(邮件列表上的讨论

我建议您尝试升级到针对 Java 1.5 编译的 Spring 3.x。如果这不可能,请BaseGrantedAuthority用 Java 编写一个基类,该基类实现compareTo并委托给可以在 Scala 中实现的模板方法。