2010-10-02 14 views
10

Desidero restituire da un metodo Java un riferimento a un oggetto Scala. Come lo posso fare?Come posso passare un riferimento a un oggetto Scala in Java?

miei oggetti Scala sono come questo:

trait Environment 

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

... e voglio che il mio metodo Java per essere come questo:

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

C'è un modo per fare questo?

+0

Che errore ottieni? –

risposta

20
{ return LocalEnvironment$.MODULE$; } 

dovrebbe funzionare.


Modifica: il motivo per cui questo funziona è che Scala rappresenta gli oggetti singleton. La classe ObjectName$ contiene un campo denominato MODULE$ popolato con la singola istanza valida di tale classe. Ma esiste anche una classe chiamata ObjectName che copia tutti i metodi come metodi statici. In questo modo puoi usarlo come Java (basta chiamare lo ObjectName.methodName) nella maggior parte dei casi, e Scala può avere una vera classe da passare in giro.

Ma quando Java deve passare la classe in giro - non qualcosa di solito fatto con un mucchio di metodi statici, che è ciò che object è progettato per emulare in Java - devi quindi sapere come Scala lo rappresenta internamente.

+1

Alcune spiegazioni sarebbero buone. Si tratta di un metodo "portatile" o di $ è un artefatto di implementazione di Scala? –

+0

@Brian - Ho parzialmente risposto alla modifica. Non sono sicuro di cosa intendi per "portatile" in contrasto con "artefatto di implementazione". È entrambi - Scala utilizza uno schema di denominazione coerente per i suoi artefatti di implementazione. A differenza delle chiusure anonime, questa è facile da prevedere. –

+0

Dato 'LocalEnvironment' sembra essere un oggetto singleton standalone, dovrebbe probabilmente essere' return LocalEnvironment.MODULE $' (no '$' in 'LocalEnvironment'). –

22

Mentre il metodo $ .MODULE $ funziona, un modo leggermente meno aggressivo per ottenere l'interoperabilità Java con gli oggetti Scala è di esporre l'oggetto come metodo su se stesso.

La Scala:

object LocalEnvironment extends Environment{ 
    def instance = this 
} 

Java:

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

Questo funziona perché sotto le coperte, .Instance() viene implementato come un metodo statico sulla classe LocalEnvironment. C'è stata una discussione sugli oggetti Scala che hanno ottenuto un metodo di "istanza" di default, proprio per questo scopo.

+1

Questo è bello, ma avrebbe bisogno di alcuni commenti per spiegare lo scopo della variabile. Per quel motivo, sono andato con il MODULE $ invece. – David

+0

Concordato, interessante e +1, ma funziona solo se si dispone dell'accesso in scrittura alla sorgente dell'oggetto. Ad esempio, non funzionerà per scala.xml.TopScope. – Synesso

Problemi correlati