2010-10-02 19 views
10

Quiero regresar de un método de Java una referencia a un objeto de Scala. ¿Cómo puedo hacer eso?¿Cómo puedo pasar una referencia de objeto Scala en Java?

Mis objetos Scala son así:

trait Environment 

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

... y quiero que mi método Java para ser como esto:

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

¿Hay una manera de hacer esto?

+0

¿Qué error obtienes? –

Respuesta

20
{ return LocalEnvironment$.MODULE$; } 

debería funcionar.


Editar: la razón por la que esto funciona es que así es como Scala representa objetos singleton. La clase ObjectName$ tiene un campo llamado MODULE$ que se completa con la única instancia válida de esa clase. Pero también hay una clase llamada ObjectName que copia todos los métodos como métodos estáticos. De esta forma, puede usarlo como Java (simplemente llame al ObjectName.methodName) en la mayoría de los casos, y Scala tendrá una clase real para pasar.

Pero cuando Java necesita pasar la clase -no es algo hecho normalmente con un montón de métodos estáticos, que es lo que object está diseñado para emular en Java- entonces debe saber cómo lo representa Scala internamente.

+1

Alguna explicación sería buena. ¿Es este un método "portátil", o es $ un artefacto de implementación de Scala? –

+0

@Brian - He respondido parcialmente en la edición. No estoy seguro de lo que quiere decir con "portátil" en contraste con "artefacto de implementación". Ambas cosas: Scala usa un esquema de nombres consistente para sus artefactos de implementación. A diferencia de los cierres anónimos, este es fácil de predecir. –

+0

Dado que 'LocalEnvironment' parece ser un objeto singleton independiente, probablemente debería ser' return LocalEnvironment.MODULE $ '(no' $ 'en' LocalEnvironment'). –

22

Mientras que el método $ .MODULE $ funciona, una forma ligeramente menos discordante de obtener interoperabilidad Java con objetos Scala es exponer el objeto como un método en sí mismo.

La Scala:

object LocalEnvironment extends Environment{ 
    def instance = this 
} 

El Java:

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

Esto funciona porque debajo de las sábanas, .instance() se implementa como un método estático en LocalEnvironment clase. Se ha debatido sobre los objetos de Scala obteniendo un método de "instancia" por defecto, solo para este propósito.

+1

Esto es genial, pero necesitaría algunos comentarios para explicar el propósito de la variable. Por esa razón, en lugar de eso he optado por lo de $ MODULE. – David

+0

De acuerdo, genial y +1, pero solo funciona si tiene acceso de escritura a la fuente del Objeto. No funcionará para scala.xml.TopScope, por ejemplo. – Synesso

Cuestiones relacionadas