Scala中的语言特性是如何实现的?

#思特沃克好声音#

(图片:网络)

我们学东西不止要知其然,还要知其所以然。成都办公室的崔鹏飞在学Scala的时候,不止学习如何使用Scala,也研究了Scala中的语言特性是如何实现的。

Scala中的语言特性是如何实现的(1)

Scala可以编译为Java bytecode和CIL,从而在JVM和CLI之上运行。Scala有很多在Java和C#的世界中显得陌生的语言特性,本文将分析这些语言特性是如何实现的。

object

Scala中可以像这样创建object:

然后在代码的其他地方调用printSomething,一个object究竟是什么东西呢? 我们将这段Scala编译为Java bytecode,然后反编译为Java,会发现编译器为HowIsObjectImplementedInScala这个object生成了两个类:

第一个类只包含一个静态方法,其实现依赖于第二个叫做HowIsObjectImplementedInScala$的类。

HowIsObjectImplementedInScala$是一个单例,其静态块实例化自己并把this赋值给MODULE$这个public static的成员,从而可以被外界访问。

同样,我们可以把这段代码编译为CIL,然后反编译为C#:

和Java代码大同小异,除了静态构造和某几个关键字外,基本一样。一个object就是一个Scala编译器帮我们实现的singleton。

var和val

var:可变。val:不可变。关于这两个关键字何时该使用哪一个,这里不做讨论,我们只是观察这二者在编译后是如何被表示的。

这段Scala代码:

定义了两个字段一个var,一个val,方法中定义了两个局部变量,一个var,一个val。

编译为Java bytecode并反编译之后:

声明为字段的v1和v2,一个是普通字段,另一个则被标记为final。编译器为v1生成了getter和setter,为v2则只有getter,因为v2作为immutable的字段是不可以被重新赋值的。

有趣的是方法中的局部变量都是普通的变量,没有被final修饰。

再来看这段Scala编译为CIL再反编译为C#之后的样子:

有一个明显的问题,v2没有标为readonly(C#世界中用于声明变量不可以重新赋值的关键字),这是compiler的bug吗?

除此之外,和Java代码一致。但是有趣的是代码中的所有public方法(包括上一段演示object的代码)都被标为了override,原因不明。

小结

本来以为研究这么简单的两个语言特性不会有啥收获,仅仅是反编译一下,看看compiler都做了啥,满足下好奇心罢了。

结果还是有意外收获,我在反编译后的代码中发现了三个有趣的问题:

  • 在Scala中被声明为val的v4为什么在反编译的Java中不是final的呢?
  • 在Scala中被声明为val的v2为什么在反编译的C#中不是readonly的呢?
  • 为什么反编译出来的C#代码中的实例级公开方法都是标有override的呢?

为什么呢?为什么呢?为什么呢?答案下期揭晓。

原文发布于微信公众号 - 思特沃克(ThoughtWorks)

原文发表时间:2014-04-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

java到底和C++有啥区别?

作为一名C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且Java的语法无疑是非常熟悉的。事实上,Java本来就是从C++衍生出来的。 然而,C++和...

39360
来自专栏java一日一条

Java集合框架综述

近被陆陆续续问了几遍HashMap的实现,回答的不好,打算复习复习JDK中的集合框架,并尝试分析其源码,这么做一方面是这些类非常实用,掌握其实现能更好的优化我们...

11040
来自专栏IT派

Code | Python30个编程技巧!

1. 原地交换两个数字 Python 提供了一个直观的在一行代码中赋值与交换(变量值)的方法,请参见下面的示例: ? 3. 使用三元操作符来进行条件赋值 三元...

37140
来自专栏IT派

JavaScript 打怪升级 —— 把业务逻辑当练习题做

开发项目和出没社区有一段时间了,会遇上一些比较有印象业务需求。这些业务需求,可能是自己开发项目遇上的,可能是在社区看到的业务需求,或者其他情况接触到的需求,但是...

8630
来自专栏Java技术分享圈

杨老师课堂_Java教程第五篇之函数运用

今天主要是讲解以下知识点: 1、方法基础知识 2、方法高级内容 3、方法案例

10120
来自专栏GreenLeaves

C# 泛型

1、泛型的优势 在日常开发中,我们经常会开发一些特殊的功能,而这个功能适用于多个类型(比如string,int等多种类型),最简单的做法是给每种类型都做一个实现...

200100
来自专栏积累沉淀

Java设计模式(十四)----模板方法模式

模板方法模式 一、概述 二、结构 三、具体案例 四、优缺点和设计思想 一、概述 模板方法模式是类的行为模...

22850
来自专栏aCloudDeveloper

从一个集合中查找最大最小的N个元素——Python heapq 堆数据结构

Top N问题在搜索引擎、推荐系统领域应用很广, 如果用我们较为常见的语言,如C、C++、Java等,代码量至少也得五行,但是用Python的话,只用一个函数就...

248100
来自专栏做全栈攻城狮

Python学习入门教程,字符串函数扩充详解

因有用户反映,在基础文章对字符串函数的讲解太过少,故写一篇文章详细讲解一下常用字符串函数。本文章是对:程序员带你十天快速入门Python,玩转电脑软件开发(三)...

8920
来自专栏叁金大数据

自学Python六 爬虫基础必不可少的正则

  要想做爬虫,不可避免的要用到正则表达式,如果是简单的字符串处理,类似于split,substring等等就足够了,可是涉及到比较复杂的匹配,当然是正则的天下...

9310

扫码关注云+社区

领取腾讯云代金券