Используйте константы Scala в Java

Я сейчас оцениваю Scala для будущих проектов и наткнулся на что-то странное. Я создал следующую константу для нас в JSP:

val FORMATED_TIME = "formatedTime";

И это не сработало. После некоторых экспериментов я решил декомпилировать, чтобы докопаться до сути:

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

Теперь это интересно! Лично я довольно долго задавался вопросом, зачем инспектору нужен префикс get и мутатор префикса, установленный в Java, поскольку они живут в разных пространствах имен.

Однако все еще может быть неловко объяснять это остальной части команды. Так возможно ли иметь публичную константу без инспектора?

2 ответа

Решение

Это из-за принципа унифицированного доступа, а именно: методы и поля неразличимы

Смотрите этот ответ

В Scala 2.8.0 это означает, что если у вас есть объект-компаньон, вы потеряете статические пересылки)

Если у вас есть это в Scala:

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

Вы можете использовать это так из Java

//Java

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

Также см. Книгу Scala в глубине

Также обратите внимание на @scala.reflect.BeanProperty для классов.

Я еще раз изучил декомпилированный код и заметил кое-что еще. Переменные на самом деле не являются статическими. Поэтому моей следующей идеей было использовать вместо этого объект:

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

Но теперь все становится действительно ужасно

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

Таким образом, я получил дополнительный класс, заканчивающийся на $, который имеет одноэлементный экземпляр с именем MOUDLE$. И еще есть инспектор. Таким образом, доступ к переменной внутри jsp становится:

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

Это работает, как ожидалось, и я лично могу жить с этим, но как я собираюсь объяснить это команде?

Конечно, если есть более простой способ, мне нравится об этом слышать.

Другие вопросы по тегам