【问题标题】:How protected method in scala works on jvmscala中的受保护方法如何在jvm上工作
【发布时间】:2015-05-03 04:05:16
【问题描述】:

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

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 也设置在Java 方法ignite 的描述符中。

但它仍然提供与 JAVA 不同的行为。

这东西JVM是怎么处理的?

注意:我没有深入了解 JVM 规范。

【问题讨论】:

  • 这可能是编译器在某些时候强制执行“可见性”;另外,Scala 中的“受保护”是什么意思?
  • Java 保护方法可以在其他包和子类中访问,而 Scala 保护方法只能在子类中访问。
  • @Mitesh 你应该让你的评论成为答案。

标签: java scala jvm protected


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    正如@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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-11
      • 1970-01-01
      • 2012-01-26
      • 2016-11-24
      • 2015-04-23
      • 2020-03-31
      • 2011-05-25
      • 1970-01-01
      相关资源
      最近更新 更多