8

我目前正在为未来的项目评估 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需要在 Java 中设置的前缀,因为它们存在于不同的名称空间中。

然而,向团队的其他成员解释这一点可能仍然很尴尬。那么是否有可能在没有检查员的情况下拥有一个公共常量?

4

2 回答 2

11

这是因为统一访问原则,即:方法和字段是不可区分的

看到这个答案

在 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

于 2010-10-05T13:10:43.110 回答
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 ());

这按预期工作,我个人可以忍受它,但我要如何向团队解释呢?

当然,如果有更简单的方法我喜欢听到它。

于 2010-10-05T08:45:02.750 回答