scala 中的受保护方法如何在 jvm 上工作

How protected method in scala works on jvm

我是 Scala 的新手。我读到 Scala 的 protected 关键字与 Java 中的 protected 不同。当我在 Scala 和 java 中看到为 public class 的受保护方法生成的字节码时,我发现以下内容:

Scala 代码:

package com.test 
class Vehicle {
  protected def ignite() {
    println("Ignition.....")
  }
}

当我使用javap反编译时,显示如下代码:

public class com.test.Vehicle {
  public void ignite();
  public com.test.Vehicle();
}

并且 flags: ACC_PUBLIC 在 Scala 方法 ignite 的描述符中设置。

等效Java代码:

package com.test;
public class Vehicle {
  protected void ignite() {
    System.out.println("Ignition.....");
  }
}

和反编译代码:

public class com.test.Vehicle {
  public com.test.Vehicle();
  protected void ignite();
}

并且 flags: ACC_PROTECTED 在方法 ignite 的描述符中设置为 Java。

但它仍然给出了与 JAVA 不同的行为。

JVM是怎么处理这个东西的?

注意:我对 JVM 规范了解不深。

Scala protected(以及其他不直接对应于任何 JVM 限定符的限定符)根本不由 JVM 处理;它仅由 Scala 编译器强制执行,并且仅适用于 Scala,因此任何其他语言都可以访问此方法(因为就 JVM 而言,它是 public)。

正如@Alexey 回答的那样,所有修饰符仅限于编译器。与 JVM 完全没有关系。一旦生成字节码,就不会在 JVM 级别上对访问修饰符进行交叉检查。

考虑以下程序:

package Protected {
  package test {
    class Vehicle {
      protected def checkEngine() {}

      private[Protected] def ignite() {}

      private[test] def injectFuel() {}

      private[this] def openInletValve() {}

      def start() {}
    }
  }
}

反编译代码使用javap

public class Protected.test.Vehicle {
  public void checkEngine();
  public void ignite();
  public void injectFuel();
  public void start();
  public Protected.test.Vehicle();
}