2010-10-05 8 views
8

Actualmente estoy evaluando Scala para proyectos futuros y encontré algo extraño. Creé la siguiente constante para nosotros en un JSP:Usar constantes de Scala en Java

val FORMATED_TIME = "formatedTime"; 

Y no funcionó. Después de algunos experimentos que decidí descompilar llegar al fondo del mismo:

private final java.lang.String FORMATED_TIME; 

public java.lang.String FORMATED_TIME(); 
    Code: 
    0: aload_0 
    1: getfield #25; //Field FORMATED_TIME:Ljava/lang/String; 
    4: areturn 

Ahora que es interesante! Personalmente me he estado preguntando durante bastante tiempo por qué un inspector necesita el prefijo obtener y un mutador el prefijo conjunto en Java ya que viven en diferentes espacios de nombres.

Sin embargo, puede ser incómodo explicar eso al resto del equipo. Entonces, ¿es posible tener una constante pública sin el inspector?

Respuesta

11

Esto es debido a la Uniform Access Principle, es decir: los métodos y campos son indistinguibles

Ver this answer

En Scala 2.8.0 esto significa que si usted tiene un objeto acompañante, se pierde el estática transitarios)

Si usted tiene esto en Scala:

//Scala 
object CommonControler { 
     val FORMATED_TIME = "formatedTime"; 
} 

Usted puede utilizar de esta manera desde Java

//Java 

// Variables become methods 
CommonControler$.MODULE$.FORMATED_TIME(); 
// A static forwarder is avaliable 
CommonControler.FORMATED_TIME(); 

Véase también el libro Scala in Depth

También tenga en cuenta el @scala.reflect.BeanProperty para las clases.

+0

Tengo que comprobar eso de nuevo, porque Me falta el promotor.Tuve un reenviador en la 2da clase que creé. – Martin

+1

Creo que lo descubrí. Si tiene una clase CommonControler y objeta CommonControler, entonces no obtendrá los reenviadores estáticos :-(. – Martin

1

Eché un vistazo al código descompilado y noté algo más. Las variables no son realmente estáticas. Así que mi siguiente idea era utilizar un objeto en su lugar:

object KommenControler 
{ 
    val FORMATED_TIME = "formatedTime"; 
} // KommenControler 

Pero ahora las cosas se ponen realmente feas:

public final class ….KommenControler$ extends java.lang.Object implements scala.ScalaObject{ 

public static final ….KommenControler$ MODULE$; 

private final java.lang.String FORMATED_TIME; 

public static {}; 
    Code: 
    0: new #9; //class …/KommenControler$ 
    3: invokespecial #12; //Method "<init>":()V 
    6: return 

public java.lang.String FORMATED_TIME(); 
    Code: 
    0: aload_0 
    1: getfield #26; //Field FORMATED_TIME:Ljava/lang/String; 
    4: areturn 

por lo que obtener una clase adicional que finaliza el $ que tiene una instancia singleton llamada MOUDLE $. Y todavía hay el inspector. Por lo que el acceso a la variable dentro de una JSP se convierte en:

final String formatedTime = (String) request.getAttribute (….KommenControler$.MODULE$.FORMATED_TIME()); 

Esto funciona como se esperaba y yo personalmente puedo vivir con ella, pero ¿cómo voy a explicar que al equipo?

Por supuesto, si hay una manera más simple me gusta saber de ella.

+1

Deberías envolverlo en un bonito objeto java para abstraer la llamada fea pero necesaria. De hecho, en Java, siempre debe encapsular las constantes finales estáticas públicas en la llamada al método para evitar que se incluyan en la compilación. – paradigmatic

+0

Ver esta respuesta: http://stackoverflow.com/questions/3282653/how-do-you-call-a-scala-singleton-method-from-java/3445597#3445597 – oluies

Cuestiones relacionadas