Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Scala constants in Java

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?

like image 551
Martin Avatar asked Oct 05 '10 06:10

Martin


2 Answers

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.

like image 120
oluies Avatar answered Oct 21 '22 02:10

oluies


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.

like image 31
Martin Avatar answered Oct 21 '22 02:10

Martin