【问题标题】:Scala: Can I declare a public field that will not generate getters and setters when compiled?Scala:我可以声明一个在编译时不会生成 getter 和 setter 的公共字段吗?
【发布时间】:2012-05-08 00:14:26
【问题描述】:

在 Scala 中,当您声明 val 或 var 时,Scala 会在编译为字节码时自动为您生成私有字段以及 getter 和 setter。

例如

class myClass {
    val name = "My Name"
}

将编译以创建等效项

class myClass {
    private string name;
    public string name();
    public void name_$eq(string);
}

其中 name() 和 name_$eq 是私有字符串名称的 getter 和 setter。

我知道您可以通过将私有字段声明为 private[this] val/var blah 来强制它不为私有字段提供 getter 和 setter,但我需要能够创建一个不生成 getter 和编译时设置器。

这在 Scala 中是否可行?

谢谢

【问题讨论】:

  • 它不会为 vals 创建 setter

标签: scala


【解决方案1】:

生成的类不包含您提供的示例中的 getter 或 setter。 生成的类不包含 java bean getter 或 setter。要真正使编译器为var 生成getX 和setX 方法,您需要使用@BeanProperty 注释该变量。

如果您想从 java 访问公共字段,我认为您很不幸。至少,我还没有看到仅使用 scala 的方法。

你可以通过混合 scala 和 java 来完成它。使用类似的 java 类:

public abstract class JavaClassWithPublicField {
   public String name = "My name";
}

然后在你的 scala 代码中继承那个类:

class ScalaClassWithPubilcField extends JavaClassWithPublicField

这可能是最干净的方法。

【讨论】:

  • 更新了答案,因为我意识到你可以通过混合 java 和 scala 来解决这个问题。
  • “getter”不是称为getX 的方法,“setter”也不是称为setX 的方法。由于语言的语法限制,Java 对 getter 和 setter 名称有这种约定。 Scala 没有,getter 称为 x,而 setter 称为 x_=(或从 Java 中看到的 x_$eq)。
  • 感谢@DanielC.Sobral 的澄清,我稍微更改了答案以使区分更加清晰。不过,第一部分现在可能有点话题......
  • 我认为你是对的,唯一的办法就是将 Scala 与 Java 混合使用。
【解决方案2】:

您可能想强制使用属性的表示方式,因为您是从 Java 访问的。 (如果你试图通过摆脱 getter 来“优化”你的字节码,那么你就是在浪费时间,VM 会快速内联它们。)对你来说不幸的是,为未来尽可能敞开大门改进,Scala 规范don't specify how Scala code should be translated to byte code。这意味着,即使您找到适用于给定版本的 Scala 的技巧,也不能保证在后续版本中也有效。

在这些情况下,推荐的方法是用 Java 编写 Java 可见的代码,然后用 Scala 编写一个小的粘合类 - 就像@Emil 给出的答案一样棒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    相关资源
    最近更新 更多