2014-06-10 10 views
6

Ich habe eine Scala-Klasse, die versucht, eine Java-Schnittstelle zu implementieren (EntityManager in JavaEE 7 für Komponententests, um spezifisch zu sein). Die Schnittstelle hat diese beiden Methoden (ua):Wie implementiert man Java-Schnittstelle in Scala mit mehreren Variablen-Parameter-Methoden (Typ Eraser Problem)?

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

In der Scala Implementierung ich habe:

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

Allerdings habe ich die folgende Fehlermeldung erhalten:

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 = ??? 

Ich habe nicht war in der Lage, mit einer Arbeit zu kommen. Meine Google-Suchanfragen konnten nicht gefunden und beantwortet werden. Ich benutze Scala 2.10.4.

Antwort

2

AFAIK die EntityManager Java-Schnittstelle kann nicht direkt in Scala implementiert werden. Die Java-Varargs werden in der ersten Methode in Seq[Class[_]] und in der zweiten Methode in Seq[String] konvertiert. Aufgrund des Löschens scheinen beide Methoden dieselbe Signatur zu haben createStoredProcedureQuery(String, Seq[_]).

Ich kann nur eine Abhilfe für dieses Problem vorschlagen. Sie sollten eine Java abstrakte Klasse schreiben, die durch das Delegieren an 2 andere abstrakte Methoden mit unterschiedlichen Namen, um eindeutig zu machen, die EntityManager Schnittstelle und implementieren die 2 anstößigen Methoden erweitert:

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); 

}

Jetzt können Sie die verlängern abstrakte Klasse von Scala und implementieren Sie die disambiguated Methoden:

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

    override def createStoredProcedureQueryForResultSetMappings(procedureName: String, resultSetMappings: String*) = ??? 
} 
+0

Danke. Das hat funktioniert. Bedeutet dies, dass es ein "Loch" in der Sprache gibt? Wenn Scala mit Java verbunden werden soll, scheint es, dass es Java-Varargs (zusätzlich zu den besseren Scalarargs) unterstützen sollte. – Integrator

+0

Das Problem ist nicht mit Varargs per se, sondern die Interaktion zwischen Varargs und Methodenüberladung. Java hat komplizierte Regeln, die auf dem Compiler fest codiert sind, um die Mehrdeutigkeiten aufzulösen. Mein Verständnis ist, dass die Scala-Designer entschieden haben, dass sie bessere Dinge zu tun haben, als diese Regeln im Scala-Compiler neu zu implementieren ... Also, Scala hat einige Teile, die nicht mit Java kompatibel sind und wir müssen immer noch auf Java zurückgreifen, um zu funktionieren um diese Einschränkungen herum. – Jelmo

Verwandte Themen