3

来自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 程序调用方法startsWithsubstringof String,这是在 Java 中定义的类。它还访问outJava 类的静态字段System,并调用其(重载)println方法。即使 Scala 没有静态类成员的概念,这也是可能的。事实上,每个 Java 类在 Scala 中都被视为两个实体,一个包含所有动态成员的类和一个包含所有静态成员的单例对象。

我了解将 Scala 的伴随对象翻译成 Java 字节码,但我不确定对于相反的示例(从 Java 到 Scala) ,上部块引用中的粗体文本“在 Scala 中看到”到底是什么意思。

这是否意味着具有静态成员的 Java 类实际上被转换或只是解释为 Scala 中的两个实体?还是我的两个假设都是错误的?

4

2 回答 2

5

我认为您可能被 Java 假设蒙蔽了双眼。考虑这个简单的代码片段:

X.Y()

这意味着该方法Y正在对象上调用X,或者在其他一些X隐式转换为的对象上调用。

也许这看起来并不奇怪,或者你看不出有什么不妥,所以让我们明确说明一个结果:X永远不会是一个 class。您不会在类上调用方法,期间。

自然地,这给 Java 带来了关于静态成员的严重互操作性问题,这就是为什么声明 Java 类的静态成员X将被“视为”为单例对象的原因:因为否则,您将永远无法使用它们.

请注意,Scala 的单例对象是真正的对象——它们是单例类的实例。但是,具有静态成员的 Java 类不会产生单个对象。在实践中,这意味着这一行:

val x = X

如果X是 Scala 单例对象,则可以使用,但如果它是具有静态成员的 Java 类,则无法使用。

于 2012-03-28T15:03:06.540 回答
1

它只是意味着 scala 不会对初始 java 代码进行任何更改,其中静态成员和非静态成员在同一个类中。

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

我猜这本书使用了看到而不是解释,因为如果您考虑“解释语言”(在这种情况下没有意义),最后一个可能有不同的含义。

于 2012-03-28T11:31:56.020 回答