Scala中的val与Java中的const有何不同?

6

有人能详细解释一下scala中的val和java中的const有什么不同吗?
它们之间的技术差异是什么?我相信我理解了c++和java中的"const"是什么意思。我感觉"val"在某种程度上不同于"const",并且更好,但我无法确切说明。谢谢


不要忘记,val/var也用于通用地标记字段和局部变量/值,以便您无需声明类型。在Scala中,val x实际上更接近于C++中的const auto x - DaoWen
2个回答

11

Java中的const关键字没有实际用途——它被保留了,但无法用于任何操作。在Java中声明一个变量为final与其大致等效

在Scala中将变量声明为val与在Java中声明为final具有类似的保证,但除非将其声明为private[this],否则Scala中的val是实际方法。下面是一个示例:

class Test(val x: Int, private[this] val y: Int) {
  def z = y
}

这就是编译后的class文件样子:

$ javap -p Test
Compiled from "Test.scala"
public class Test {
  private final int x;
  private final int y;
  public int x();
  public int z();
  public Test(int, int);
}

从这个例子清楚地可以看出,private[this] val 实际上是 Scala 对 Java 中的 final 的等效表示,它只创建了一个字段(没有 getter 方法)。然而,它是私有字段,所以即使如此也并不完全相同。

另一个有趣的事实是:Scala 也有一个 final 关键字! Scala 的 final 行为类似于 Java 中用于 final ——它防止重写。以下是另一个例子:

final class Test(final val x: Int, final var y: Int) { }

并生成以下类:

$ javap -p Test
Compiled from "Test.scala"
public final class Test {
  private final int x;
  private int y;
  public final int x();
  public final int y();
  public final void y_$eq(int);
  public Test(int, int);
}

注意,final var的定义使得getter和setter方法是final的(即不能被覆盖),但不包括支持的变量本身。


0

Scala中的val相当于Java中的final变量或字段。Scala中的var相当于Java中的非final变量或字段。(顺便说一下,“var”和“const”都不是Java术语。)

Scala语法选择使用valvar的优点在于,使用不可修改的值的代码通常更容易理解。在Java中,final是“语法醋”,风格指南往往争论是否应该使用final来鼓励更好的编码或省略final以避免混乱。Scala没有这个难题,因为varval的长度完全相同,所以你可以更自由地选择最合适的一个。


在Java中,final是“语法醋”,代码风格指南倾向于争论是否应该使用final来鼓励更好的编码,还是省略final以避免杂乱无章。你有任何这些说法的引用吗?在我看来,final只是“语法糖”,就像类型一样是语法糖。泛型可能更加如此,因为它们实际上在编译时被擦除,而final修饰符仍然存在,但我从未听说过有人说泛型只是“语法糖”。我也从未听说过有人声称你应该省略final,因为它只是杂乱无章的东西! - DaoWen
关于您评论的第一部分 - 您意识到我写的是“醋”,而不是“糖”吗? - Chris Martin
我没有特别要引用的内容,只是多年来在同事和网上看到过这样的辩论。一个例子:https://programmers.stackexchange.com/questions/48413/in-java-should-i-use-final-for-parameters-and-locals-even-when-i-dont-have-t - Chris Martin
不,我没有注意到你写的是“醋”而不是“糖”,这是我的错。实际上,我以前从未见过那个术语。然而,我仍然不同意final是语法上的“醋”,因为那个定义似乎暗示着语言设计者故意让某些东西变得笨拙以阻止它(就像Scala中的冗长的asInstanceOf一样)。关于省略方法参数上的final的观点对我来说是有道理的,因为所有的finals会使签名变得臃肿。如果您编辑您的问题以特别提到方法(也许强调“醋”),那么我可以取消我的踩票。 - DaoWen
我认为它不需要是故意的才能成为醋。通常只是设计不良(比如分号)。这绝对不仅仅是方法签名的问题;它也会使方法体变得臃肿。你的踩票是你自己的事,我不需要解释。 - Chris Martin
我认为分号是“无用之物”,而不是“醋”。我可以理解你的观点,即任何在语法上让你感到恶心的东西都可能是“醋”,但看起来创造这个术语的人特别是在阻止不良实践的背景下使用它。 - DaoWen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接