问题
I am currently evaluating Scala for future projects and came across something strange. I created the following constant for us in a JSP:
val FORMATED_TIME = "formatedTime";
And it did not work. After some experimenting I decided to decompile to get to the bottom of it:
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
Now that is interesting! Personally I have been wondering for quite a while why an inspector needs the prefix get and a mutator the prefix set in Java as they live in different name-spaces.
However it might still be awkward to explain that to the rest of the team. So is it possible to have a public constant without the inspector?
回答1:
This is because of the Uniform Access Principle, i.e.: Methods and Fields Are Indistinguishable
See this answer
In Scala 2.8.0 this means if you have a companion object, you lose your static forwarders)
If you have this in Scala:
//Scala
object CommonControler {
val FORMATED_TIME = "formatedTime";
}
You may use it like this from Java
//Java
// Variables become methods
CommonControler$.MODULE$.FORMATED_TIME();
// A static forwarder is avaliable
CommonControler.FORMATED_TIME();
Also see the book Scala in Depth
Also note the @scala.reflect.BeanProperty for classes.
回答2:
I had a further look into the decompiled code and noted something else. The variables are not actually static. So my next idea was to use an object instead:
object KommenControler
{
val FORMATED_TIME = "formatedTime";
} // KommenControler
But now things turn really ugly:
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
So I get an additional class ending on $ which has a singleton instance called MOUDLE$. And there is still the inspector. So the access to the variable inside a jsp becomes:
final String formatedTime = (String) request.getAttribute (….KommenControler$.MODULE$.FORMATED_TIME ());
This works as expected and I personally can live with it but how am I going to explain that to the team?
Of course if there is a simpler way I like to hear of it.
来源:https://stackoverflow.com/questions/3861442/use-scala-constants-in-java