Используйте константы 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 ());
Это работает, как ожидалось, и я лично могу жить с этим, но как я собираюсь объяснить это команде?
Конечно, если есть более простой способ, мне нравится об этом слышать.