我目前正在评估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 和mutator前缀 set 在Java中,因为它们位于不同的名称空间中。
然而,向团队的其他成员解释这可能仍然很尴尬。那么没有检查员就可以拥有一个公共常数吗?
答案 0 :(得分:11)
这是因为Uniform Access Principle,即:方法和字段难以区分
请参阅this answer
在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 in Depth
另请注意课程的@scala.reflect.BeanProperty。
答案 1 :(得分:1)
我进一步研究了反编译代码并注意到其他内容。变量实际上不是静态的。所以我的下一个想法是使用一个对象:
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 ());
这是按预期工作的,我个人可以忍受,但我将如何向团队解释?
当然,如果有一种更简单的方式我喜欢听到它。