How to implement Java interface in Scala with multiple variable parameter methods (type eraser issue)?

时间:2021-08-26 19:36:31

I have a Scala class that is trying to implement a Java interface (EntityManager in JavaEE 7 for unit testing purposes to be specific). The interface has these two methods (among others):

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

public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses);public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings);

In the Scala implementation I have:

在Scala实现中,我有:

override def createStoredProcedureQuery(procedureName: String, resultClasses: Class[_]*): StoredProcedureQuery = ???override def createStoredProcedureQuery(procedureName: String, resultSetMappings: String*): StoredProcedureQuery = ???

However, I get the following error:

但是,我收到以下错误:

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

I have not been able to come up with a work around. My Google searches also failed to find and answer. I'm using Scala 2.10.4.

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

1 个解决方案

#1


2  

AFAIK the EntityManager Java interface cannot be implemented directly in Scala. The Java varargs are converted to Seq[Class[_]] in the first method and Seq[String] in the second method. Because of erasure, both methods then appear as having the same signature createStoredProcedureQuery(String, Seq[_]).

AFAIK EntityManager Java接口无法在Scala中直接实现。 Java varargs在第一种方法中转换为Seq [Class [_]],在第二种方法中转换为Seq [String]。由于擦除,两种方法都显示为具有相同的签名createStoredProcedureQuery(String,Seq [_])。

I can only propose a workaround for this issue. You should write a Java abstract class that extends the EntityManager interface and implement the 2 offending methods by delegating to 2 other abstract methods with different names in order to disambiguate:

我只能就此问题提出解决方法。您应该编写一个扩展EntityManager接口的Java抽象类,并通过委托其他2个具有不同名称的抽象方法来实现2个违规方法,以便消除歧义:

public abstract class EntityManagerWorkaround implements EntityManager {@Overridepublic StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {    return createStoredProcedureQueryForResultClasses(procedureName, resultClasses);}@Overridepublic 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);

}

Now you can extend the abstract class from Scala and implement the disambiguated methods:

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

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

#1


2  

AFAIK the EntityManager Java interface cannot be implemented directly in Scala. The Java varargs are converted to Seq[Class[_]] in the first method and Seq[String] in the second method. Because of erasure, both methods then appear as having the same signature createStoredProcedureQuery(String, Seq[_]).

AFAIK EntityManager Java接口无法在Scala中直接实现。 Java varargs在第一种方法中转换为Seq [Class [_]],在第二种方法中转换为Seq [String]。由于擦除,两种方法都显示为具有相同的签名createStoredProcedureQuery(String,Seq [_])。

I can only propose a workaround for this issue. You should write a Java abstract class that extends the EntityManager interface and implement the 2 offending methods by delegating to 2 other abstract methods with different names in order to disambiguate:

我只能就此问题提出解决方法。您应该编写一个扩展EntityManager接口的Java抽象类,并通过委托其他2个具有不同名称的抽象方法来实现2个违规方法,以便消除歧义:

public abstract class EntityManagerWorkaround implements EntityManager {@Overridepublic StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {    return createStoredProcedureQueryForResultClasses(procedureName, resultClasses);}@Overridepublic 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);

}

Now you can extend the abstract class from Scala and implement the disambiguated methods:

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

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