Use Scala constants in Java

你离开我真会死。 提交于 2020-01-13 08:56:04

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!