微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java中可见的Scala中的Package-private作用域

当我从 Java代码中使用Scala代码生成的字节码时,我刚刚发现了Scala范围很奇怪的行为.考虑使用Spark(Spark 1.4,Hadoop 2.6)的以下代码片段:
import java.util.Arrays;
import java.util.List;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.broadcast.broadcast;

public class Test {
    public static void main(String[] args) {
        JavaSparkContext sc = 
            new JavaSparkContext(new SparkConf()
                                .setMaster("local[*]")
                                .setAppName("test"));

        broadcast<List<Integer>> broadcast = sc.broadcast(Arrays.asList(1,2,3));

        broadcast.destroy(true);

        // fails with java.io.IOException: org.apache.spark.SparkException: 
        // Attempted to use broadcast(0) after it was destroyed
        sc.parallelize(Arrays.asList("task1","task2"),2)
          .foreach(x -> System.out.println(broadcast.getValue()));
    }
}

这个代码失败了,这是因为我在使用它之前自愿摧毁广播,但事实是,在我的心理模型中,它不应该编译,更不用说运行正常.

的确,broadcast.destroy(Boolean)被声明为private [spark],所以它不应该从我的代码可见.我会尝试看广播的字节码,但这不是我的专长,所以我更喜欢发表这个问题.另外,对不起,我太懒了,创建一个不依赖于Spark的例子,但至少你得到了这个想法.请注意,我可以使用Spark的各种包私有方法,而不仅仅是广播.

任何想法发生了什么?

解决方法

如果我们用一个更简单的例子来重构这个问题:
package yuvie

class X {
  private[yuvie] def destory(d: Boolean) = true
}

并在Java中反编译:

[yuvali@localhost yuvie]$javap -p X.class 
Compiled from "X.scala"
public class yuvie.X {
  public boolean destory(boolean);
  public yuvie.X();
}

我们看到Scala中的私有[package]在Java中公开.为什么?这来自于Java私有包不等同于Scala私有包的事实.有一个很好的解释in this post

The important distinction is that ‘private [mypackage]’ in Scala is
not
Java package-private,however much it looks like it. Scala
packages are truly hierarchical,and ‘private [mypackage]’ grants
access to classes and objects up to “mypackage” (including all the
hierarchical packages that may be between). (I don’t have the Scala
spec reference for this and my understating here may be hazy,I’m
using 07001 as a reference.) Java’s packages are not hierarchical,and
package-private grants access only to classes in that package,as well
as subclasses of the original class,something that Scala’s ‘private
[mypackage]’ does not allow.

So,‘package [mypackage]’ is both more and less restrictive that Java package-private. For both reasons,JVM package-private can’t be used to implement it,and the only option that allows the uses that Scala exposes in the compiler is ‘public.’

原文地址:https://www.jb51.cc/java/123033.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐