2010-10-02 1 views
10

Ich möchte von einer Java-Methode einen Verweis auf ein Scala-Objekt zurückgeben. Wie kann ich das machen?Wie kann ich eine Scala Objektreferenz in Java übergeben?

Meine Scala Objekte sind wie folgt aus:

trait Environment 

object LocalEnvironment extends Environment {...} 
object ServerEnvironment extends Environment {...} 

... und ich möchte, dass meine Java-Methode so sein:

Environment getEnvironment() { return LocalEnvironment; } // DOES NOT COMPILE 

Gibt es eine Möglichkeit, dies zu tun?

+0

Welchen Fehler bekommen Sie? –

Antwort

20
{ return LocalEnvironment$.MODULE$; } 

sollte funktionieren.


Bearbeiten: Der Grund, warum das funktioniert, ist, dass Scala Singleton-Objekte darstellt. Die Klasse ObjectName$ hat ein Feld namens MODULE$, das mit der einzigen gültigen Instanz dieser Klasse gefüllt ist. Aber es gibt auch eine Klasse namens ObjectName, die alle Methoden als statische Methoden kopiert. Auf diese Weise können Sie es wie Java (rufen Sie einfach ObjectName.methodName) in den meisten Fällen verwenden, und Scala bekommt eine echte Klasse, um herumzugehen.

Aber wenn Java die Klasse passieren muss - nicht etwas, das normalerweise mit einer Reihe von statischen Methoden gemacht wird, was object entwickelt wurde, um in Java zu emulieren - dann müssen Sie wissen, wie Scala es intern darstellt.

+1

Eine Erklärung wäre gut. Ist das eine 'portable' Methode oder sind die $ ein Implementierungsartefakt von Scala? –

+0

@Brian - Ich habe teilweise in der Bearbeitung geantwortet. Ich bin mir nicht sicher, was Sie mit "portabel" im Gegensatz zu "Implementierungsartefakt" meinen. Es ist beides - Scala verwendet ein konsistentes Namensschema für seine Implementierungsartefakte. Im Gegensatz zu anonymen Schließungen ist dieser leicht vorhersehbar. –

+0

Da 'LocalEnvironment' scheinbar ein eigenständiges Singleton-Objekt ist, sollte es wahrscheinlich' return LocalEnvironment.MODULE $ 'sein (kein' $ 'in' LocalEnvironment'). –

22

Während die $ .MODULE $ -Methode funktioniert, ist ein etwas weniger erschütternder Weg, um Java-Interop mit Scala-Objekten zu erhalten, das Objekt als eine Methode für sich selbst zu entlarven.

Die Scala:

object LocalEnvironment extends Environment{ 
    def instance = this 
} 

Die Java:

Environment getEnvironment() { return LocalEnvironment.instance(); } 

Dies funktioniert, weil unter der Decke, .instance() als statische Methode auf Klasse LocalEnvironment implementiert ist. Es gibt einige Diskussionen darüber, dass Scala-Objekte standardmäßig eine "Instanz" -Methode erhalten.

+1

Das ist cool, aber es würde einige Kommentare brauchen, um den Zweck der Variablen zu erklären. Aus diesem Grund bin ich stattdessen mit dem MODUL $ Ding gegangen. – David

+0

Vereinbart, cool und +1, aber funktioniert nur, wenn Sie Schreibzugriff auf die Quelle des Objekts haben. Funktioniert beispielsweise nicht für scala.xml.TopScope. – Synesso