返回介绍

数学基础

统计学习

深度学习

工具

Scala

二、特殊规则

发布于 2023-07-17 23:38:22 字数 3745 浏览 0 评论 0 收藏 0

  1. 除了通用规则之外,还有一些特殊规则。

2.1 值类型

  1. 类似于 Int 这样的值类型翻译成 Java 有两种不同的方式。

    • 只要可能,编译器就会将 ScalaInt 翻译成 Javaint 从而获得更好的性能。

    • 但有时候做不到,因为编译器不确定它正在翻译的是一个 Int 还是另外某种数据类型。如:尽管 List[Any](1,2,3) 只包含 Int 类型的元素,但是编译器无法确认这一点。

      对于这样的情况,编译器不确定某个对象是不是值类型,因此会选择使用对象类型并依赖相应的包装类(例如 java.lang.Integer )。

2.2 单例对象

  1. Java 并没有单例对象的确切概念,不过Java 有静态方法。Scala 对单例对象的翻译采取了静态方法和实例方法相结合的方式。

    对于每个Scala 单例对象,编译器都为这个对象创建了一个名称加美元符号 $Java 类。例如:对于名叫 App 的单例对象,编译器产出一个名为 App$Java 类。这个 Java 类拥有 Scala 单例对象的所有方法和字段。另外,这个 Java 类还有一个名为 MODULE$ 的静态字段,它保存了该类在运行期间创建的一个实例。

    例如,Scala 单例对象:

    
    object App{
      def main(args: Array[String]) ={
        println("Hello world")
      }
    }

    将被翻译成一个 JavaApp$

    
    
    xxxxxxxxxx
    public final class App$ extends java.lang.Object implements scala.ScalaObject{ public static final App$ MODULE$; // 保存 APP$ 运行期间创建的一个实例 public static {}; public App$(); public void main(java.lang.String[]); public int $tag(); }
  2. 通常情况下,Scala 的单例对象翻译如前所述。但是一个重要的特例是:当面对一个”独立的“单例对象时(即没有同名的类与之对应),此时编译器将会创建一个同名的 Java 类,这个类对于每个 Scala 单例对象的方法都有一个静态方法与之对应。

    如我们有一个 App2Scala 单例对象,但是没有 App2Scala 类与之对应:

    
    
    xxxxxxxxxx
    object App2{ def main(args: Array[String]) ={ println("Hello world") } }

    则它将被翻译为:

    
    
    xxxxxxxxxx
    public final class App2 extends java.lang.Object{ public static final int $tag(); public static final void main(java.lang.String[]); }

    相反,如果你的 Scala 代码中有一个名为 App2 的类,那么 Scala 会创建相应的 JavaApp2$ 来保存你定义的成员。此时,它不会添加任何转发到同名单例对象的方法,Java 代码必须通过 MODULE$ 字段来访问这个单例。

2.3 接口

  1. 编译任何特质都会创建一个同名的 java 接口,这个接口可以作为 Java 类型使用。
  2. Java 中实现特质是另外一回事。通常情况下,这样做不切实际。
  3. 如果你写的 scala trait 仅包含抽象方法,那么这个特质会直接翻译成 java 接口。否则可能会包含额外的代码。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文