如何使用多个可变参数方法(类型橡皮擦问题)在Scala中实现Java接口?

Int*_*tor 6 scala scala-java-interop

我有一个Scala类正在尝试实现一个Java接口(JavaEE 7中的EntityManager用于特定的单元测试).界面有这两种方法(其中包括):

public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses);
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings);
Run Code Online (Sandbox Code Playgroud)

在Scala实现中,我有:

override def createStoredProcedureQuery(procedureName: String, resultClasses: Class[_]*): StoredProcedureQuery = ???
override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ???
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

MyTest.scala:134: error: double definition:
method createStoredProcedureQuery:(procedureName: String, resultSetMappings: String*)javax.persistence.StoredProcedureQuery and
method createStoredProcedureQuery:(procedureName: String, resultClasses: Class[_]*)javax.persistence.StoredProcedureQuery at line 133
have same type after erasure: (procedureName: String, resultSetMappings: Seq)javax.persistence.StoredProcedureQuery
override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ???
Run Code Online (Sandbox Code Playgroud)

我无法想出一个解决方案.我的Google搜索也未能找到并回答.我正在使用Scala 2.10.4.

小智 2

AFAIK EntityManagerJava 接口不能直接在 Scala 中实现。Seq[Class[_]]Java 可变参数在第一个方法和Seq[String]第二个方法中被转换。由于擦除,两种方法都显示为具有相同的签名createStoredProcedureQuery(String, Seq[_])

我只能针对这个问题提出一个解决方法。您应该编写一个扩展该EntityManager接口的 Java 抽象类,并通过委托给另外 2 个具有不同名称的抽象方法来实现这 2 个有问题的方法,以消除歧义:

public abstract class EntityManagerWorkaround implements EntityManager {
@Override
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {
    return createStoredProcedureQueryForResultClasses(procedureName, resultClasses);
}

@Override
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) {
    return createStoredProcedureQueryForResultSetMappings(procedureName, resultSetMappings);
}

public abstract StoredProcedureQuery createStoredProcedureQueryForResultClasses(String procedureName, Class... resultClasses);

public abstract StoredProcedureQuery createStoredProcedureQueryForResultSetMappings(String procedureName, String... resultSetMappings);
Run Code Online (Sandbox Code Playgroud)

}

现在您可以从 Scala 扩展抽象类并实现消除歧义的方法:

class EntityManagerImpl extends EntityManagerWorkaround {
  override def createStoredProcedureQueryForResultClasses(procedureName: String, resultClasses: Class[_]*) = ???

  override def createStoredProcedureQueryForResultSetMappings(procedureName: String, resultSetMappings: String*) = ???
}
Run Code Online (Sandbox Code Playgroud)