java - Scala - 如何在运行时保证 val 不变性

标签 java scala jvm

当我们在 java 中创建一个 final 时,它保证即使在运行时也不能更改,因为 JVM 保证了这一点。

Java 类:

public class JustATest {
    public final int x = 10;
}

Javap反编译:

编译自“JustATest.java”

public class JustATest {
  public final int x;

  public JustATest();
    Code:
       0: aload_0
       1: invokespecial #1                // Method java/lang/Object."<init>":()V
       4: aload_0
       5: bipush        10
       7: putfield      #2                  // Field x:I
      10: return
}

但在 scala 中,如果我们声明一个 val,它会编译成一个普通的整数,并且在反编译输出方面 var 和 val 没有区别。

原始 Scala 类:

class AnTest {

  val x = 1
  var y = 2
}

反编译输出:

Compiled from "AnTest.scala"
public class AnTest {
  public int x();
    Code:
       0: aload_0
       1: getfield      #14                 // Field x:I
       4: ireturn

  public int y();
    Code:
       0: aload_0
       1: getfield      #18                 // Field y:I
       4: ireturn

  public void y_$eq(int);
    Code:
       0: aload_0
       1: iload_1
       2: putfield      #18                 // Field y:I
       5: return

  public AnTest();
    Code:
       0: aload_0
       1: invokespecial #25                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iconst_1
       6: putfield      #14                 // Field x:I
       9: aload_0
      10: iconst_2
      11: putfield      #18                 // Field y:I
      14: return
}

根据这些信息,val 的不变性概念仅在编译时由 scala 编译器控制?这在运行时如何保证?

最佳答案

在 Scala 中,通过 val 传递不变性是一种编译时执行,它与发出的字节代码无关。在 Java 中,您声明当字段为 final 时,为了不对其进行重新分配,而在 Scala 中,使用 val 声明变量仅意味着它不能被重新分配重新分配,但它可以被覆盖。如果您希望一个字段是final,您需要像在 Java 中那样指定它:

class AnTest {
  final val x = 10
}

产生:

public class testing.ReadingFile$AnTest$1 {
  private final int x;

  public final int x();
    Code:
       0: bipush        10
       2: ireturn

  public testing.ReadingFile$AnTest$1();
    Code:
       0: aload_0
       1: invokespecial #19                 // Method java/lang/Object."<init>":()V
       4: return
}

这等同于您在 Java 中看到的字节码,只是编译器为 x 发出了一个 getter。

关于java - Scala - 如何在运行时保证 val 不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39893661/

相关文章:

java - BufferReader 不会遍历整个文本

java - 为什么在 java 中不允许分配到 'this'?

java - 为什么 Solr 不按最大相似度因子进行排名?

unit-testing - 无法从仅 jvm 模块访问 commonMain 多平台类

java - 尝试在 EditText 中将数字设置为文本

scala - 为什么拦截命令在 scala 2.11.7 上不起作用

Scala — 谓词的否定

scala - 在迭代字符串、kmer 计数时返回 Map 列表的函数

windows - java.net.SocketException : No buffer space available (maximum connections reached? ): JVM_Bind

java - 获取其他jvm的内存使用详情