2011-10-19 14 views
11

En Scala, podemos escribir¿Cuál es el equivalente Java de un objeto Scala?

object Foo { def bar = {} } 

cómo es esto en práctica por el compilador? Soy capaz de llamar desde Java Foo.bar(); pero new Foo(); desde Java da el error cannot find symbol symbol: constructor Foo()

  • ¿El únicos apoyo JVM de forma nativa?
  • ¿Es posible tener una clase en Java que no tenga un constructor?

Nota: aquí está la salida de código por scalac -print

package <empty> { 
    final class Foo extends java.lang.Object with ScalaObject { 
    def bar(): Unit =(); 
    def this(): object Foo = { 
     Foo.super.this(); 
    () 
    } 
    } 
} 

Respuesta

11

Soporte para conjuntos unitarios no está en un nivel de lenguaje, pero el lenguaje proporciona suficientes instalaciones para crearlos sin ningún problema.

Considere el siguiente código:

public class Singleton { 
    private static final Singleton instance = new Singleton(); 

    // Private constructor prevents instantiation from other classes 
    private Singleton() {} 

    public static Singleton getInstance() { 
     return instance; 
    } 
} 

Este es un ejemplo de Wikipedia, que explica cómo se puede hacer un producto único. Una instancia se mantiene en un campo privado, el constructor es inaccesible fuera de la clase, el método devuelve esta única instancia.

En cuanto a los constructores: cada clase por defecto tiene un llamado constructor por defecto, que no tiene argumentos y simplemente llama al constructor sin argumentos de la superclase. Si la superclase no tiene ningún constructor accesible sin argumentos, tendrá que escribir un constructor explícito.

Por lo tanto, una clase debe tener un constructor, pero no es necesario que la escriba si la superclase tiene un constructor sin args.

+0

ah así que el truco es hacer que el constructor privado. – Jus12

21

Al compilar el código, Scala compilador produce un equivalente del siguiente código de Java:

public final class Foo { 
    private Foo() {} // Actually, Foo doesn't have constructor at all 
        // It can be represented in bytecode, 
        // but it cannot be represented in Java language 

    public static final void bar() { 
     Foo$.MODULE$.bar(); 
    } 
} 

public final class Foo$ implements ScalaObject { 
    public static final Foo$ MODULE$; 
    static { 
     new Foo$(); 
    } 
    private Foo$() { MODULE$ = this; } 
    public final void bar() { 
     // actual implementation of bar() 
    } 
} 

Aquí Foo$ es una implementación real de un producto único, mientras que Foo proporciona un método static para la interacción con Java.

+0

¿Hay alguna forma de ver el código Java "intermedio", como lo has mostrado? ¿Usaste un descompilador para generarlo? – Jus12

+1

@ Jus12: Quizás algunos descompiladores puedan mostrarlo, pero lo reconstruí manualmente de la salida de 'javap -c -privado Foo' /' javap -c -privado Foo $ ' – axtavt

Cuestiones relacionadas