Java静态类成员和Scala互操作性

4

来自第二版《Scala编程语言概述》:

// Scala
object PrintOptions {
    def main(args: Array[String]): Unit = {
        System.out.println("Options selected:")
        for (val arg <- args)
            if (arg.startsWith("-"))
                System.out.println(" " + arg.substring(1))
    }
}

在上面的示例中,Scala程序调用了Java中定义的类String的方法startsWith和substring。它还访问了Java类System的静态字段out,并调用了其(重载的)println方法。尽管Scala没有静态类成员的概念,但这是可能的。事实上,每个Java类在Scala中都被视为两个实体:一个包含所有动态成员的类和一个包含所有静态成员的单例对象。
我理解Scala的伴生对象转换为Java字节码的翻译,但我不确定上述引用中粗体文本“在Scala中看到”的确切含义,反之亦然(从Java到Scala的相反情况)。
这是否意味着具有静态成员的Java类实际上被转换或只是在Scala中作为两个实体进行解释?或者我的两种假设都是错误的?

1
关于你的编辑:问题是什么? ;) - Nicolas
2个回答

5
我认为你可能被Java的假设蒙蔽了。考虑下面这个简单的代码片段:
X.Y()

这意味着方法Y是在对象X上调用的,或者在某个将X隐式转换为其他对象的对象上调用的。
也许这看起来并不令人惊讶,你可能没有发现任何错误,因此让我们明确一下一个结论:X永远不会是一个类。你不会在类上调用方法。
显然,这对于Java的静态成员存在严重的互操作问题,这就是为什么Java类X的静态成员将被“视为”单例对象的原因:否则,你将无法使用它们。
请注意,Scala的单例对象是真正的对象——它们是单例类的实例。但Java类的静态成员不会导致单个对象。在实践中,这意味着以下代码行:
val x = X

如果X是Scala单例对象,它将起作用,但如果它是具有静态成员的Java类,则不起作用。


1

这意味着Scala不会改变任何初始的Java代码,其中静态成员和非静态成员位于同一类中。

因此,你的第二个假设是正确的,第一个假设是错误的。

我想作者在书中使用“seen”而不是“interpreted”,因为如果你考虑“解释语言”(在那个上下文中毫无意义),后者可能有不同的含义。


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