Scala入门1(单例对象和伴生类)
一、Hello World程序的执行原理
参考http://blog.csdn.net/zhangjg_blog/article/details/22760957
object HelloWorld{
def main(args : Array[String]){
println("HelloWorld")
}
}
以object关键字修饰的一个雷鸣,这种语法叫做孤立对象,这个对象是单例的。相当于将单例类和单例对象同时定义。(即这个类不能再创建一个实例,在类初始化的时候有、, 就会创建唯一的对象)
我们在编译时生成了HelloWorld$.class(称其为虚构类)和HelloWorld.class两个.class文件:
1.传统意义上的入门main方法被编译在HelloWorld.class中
2.在HelloWorld.class中的main方法中,会访问HelloWorld$.class中的静态字段MODULE$(这个字段的类型就是HelloWorld$),并使用这个字段调用HelloWorld$中的main方法
所以,真正执行操作的是HelloWorld$.class文件。
二、孤立对象的实现原理
参考http://blog.csdn.net/zhangjg_blog/article/details/23376465
孤立对象指的是只有一个使用object关键字定义的对象, 伴生对象是指有一个使用object关键字定义的对象, 除此之外还有一个使用class关键字定义的同名类, 这个同名的类叫做伴生类。
object Test {
val a = "a string";
def printString = println(a)
}
我们在编译时生成了Test$.class和Test.class两个.class文件:
源码中的属性a对应一个静态的同名方法a(), 源码中的方法printString也对应一个静态的同名方法printString()。 静态方法a()调用Test$类中的静态字段MODULE$的a方法。 静态方法printString()调用Test$类中的静态字段MODULE$的printString方法。
object Main {
//scala main
def main(args : Array[String]){
Test.printString
}
}
在Main$中的成员方法main中, 直接调用了Test$.MODULE$.printString()方法, 而绕过了Test类, 这也是合理的, 因为只有Test$才处理相关逻辑。
Main.class提供JVM的入口函数, 在入口函数中调用Main$的成员方法main, 而Main$的成员方法main又调用了Test$的成员方法printString来处理相关逻辑, 即打印字符串。

三、伴生对象的实现原理
参考http://blog.csdn.net/zhangjg_blog/article/details/23462695
class Test{
var field = "field"
def doSomeThing = println("do something")
}
object Test {
val a = "a string";
def printString = println(a)
}
伴生对象, 也是一个Scala中的单例对象, 使用object关键字修饰。 除此之外, 还有一个使用class关键字定义的同名类, 这个类和单例对象存在于同一个文件中, 这个类就叫做这个单例对象的伴生类, 相对来说, 这个单例对象叫做伴生类的伴生对象。
编译这个文件, 同样生成两个class, 一个Test.class和一个Test$.class:
源码中的单例对象中的字段和方法都在虚构类中有相应的对应字段和方法。虽然在这个实例中加入了伴生类,并且伴生类中也有字段和方法,但是这个字段和方法并没有对应出现在虚构类中。这也说明,虚构类中的信息只和单例对象有关,单例对象的伴生类不会影响虚构类中的内容。
总结:
1 伴生类中定义的字段和方法, 对应同类class类中的成员字段和成员方法;
2 伴生对象中定义的字段和方法, 对应同名类中的静态方法, 所以可以认为Scala中的object关键字是静态的另一种表示方式, 只是scala将这些静态的东西也封装成了对象;
3 伴生对象中定义的字段和方法, 对应虚构类中的成员字段和方法。
4 同名类中的静态方法, 会访问单例的虚构类对象, 将相关的逻辑调用到虚构类中的成员方法中。 由于虚构类是单例的, 所以可以保证伴生对象中的字段都是唯一的。 也就是说虚构类的单例性, 保证了伴生对象(即scala中的object修饰的单例对象)中信息的唯一性。
5 伴生对象中的逻辑, 都转移到虚构类中去处理
6 伴生类中的逻辑, 都转移到同名类中的成员方法中去处理
7 需要注意,伴生类并不是单例的,它仍然可以创建多个对象, 只要在其他地方能够访问到这个伴生类
Scala入门1(单例对象和伴生类)的更多相关文章
- Scala单例对象、伴生对象实战详解
1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...
- 010-Scala单例对象、伴生对象实战详解
010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被 ...
- Scala单例对象和伴生对象
1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...
- 【scala】类的定义和单例对象
一.类的定义 Scala类的定义跟JAVA中类的定义基本是一样的. 示例 class ChecksumAccumulator{ var sum = 0;//Scala默认关键字为public priv ...
- scala学习手记14 - 单例对象
java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例.在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可.因为单例类无法初始化,所以不能向它的主构造函数传 ...
- 探索Scala(3)-- 单例对象
研究一下Scala语言的单例对象(Singleton Objects),为下一篇文章做准备. static不是keyword 上一篇文章提到过,interface并非Scala语言keyword,能够 ...
- apply 伴生对象 单例对象
apply(): 当类或者对象有一个主要用途时,apply方法提供了很好语法机制 scala> class Foo {} defined class Foo scala> object F ...
- Scala 孤立对象和单例对象方法体的用法和例子
[学习笔记] 1 以object关键字修饰一个类名,这种语法叫做孤立对象,这个对象是单例的. 相当于将单例类和单例对象同时定义.相当于java中的单例,即在内存中只会存在一个Test3实例.创建一个 ...
- Kotlin入门(18)利用单例对象获取时间
前面介绍了,使用扩展函数可以很方便地扩充数组Array的处理功能,例如交换两个数组元素.求数组的最大元素等等.那么除了数组之外,日期和时间的相关操作,也是很常见的,比如获取当前日期,获取当前时间.获取 ...
随机推荐
- PHP基础知识之————匿名函数(Anonymous functions)
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数.最经常用作回调函数(callback)参数的值.当然,也有其它应用的情况. ...
- Java并发编程原理与实战三十一:Future&FutureTask 浅析
一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...
- c++刷题(9/100):链表
题目一:https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tP ...
- 【leetcode 简单】 第九十二题 第N个数字
在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...中找到第 n 个数字. 注意: n 是正数且在32为整形范围内 ( n < 231). 示例 1: ...
- 彻底搞懂字符编码(unicode,mbcs,utf-8,utf-16,utf-32,big endian,little endian...)[转]
最近有一些朋友常问我一些乱码的问题,和他们交流过程中,发现这个编码的相关知识还真是杂乱不堪,不少人对一些知识理解似乎也有些偏差,网上百度, google的内容,也有不少以讹传讹,根本就是错误的(例如说 ...
- 公司内网yum源
新增yum源配置文件 vi /etc/yum.repos.d/szyum.repo 内容如下: #[redhat6.3] [base] name=redhat63 baseurl=http://10. ...
- JAVA汉字转拼音(取首字母大写)
import net.sourceforge.pinyin4j.PinyinHelper;import net.sourceforge.pinyin4j.format.HanyuPinyinCaseT ...
- C++模板(Templates)
模板(template)是泛型编程的基础,"泛型"的含义就是没有不依赖具体的数据类型.模板的引入是为了创建一般性的类(模板类)或者函数(模板函数).典型的容器比如迭代器/算法等是泛 ...
- 你真的了解js伪数组吗?深入js伪数组
关于js伪数组 具有length属性: 按索引方式存储数据: 不具有数组的push().pop()等方法: 你可能知道怎么把伪数组转换为数组,但是你知道这里边的原理吗? 假如页面有一组li元素 < ...
- [转] Cacti+Nagios监控平台完美整合
Cacti+Nagios监控平台完美整合 http://os.51cto.com/art/201411/458006.htm 整合nagios+cacti+微信.飞信实现网络监控报警 http://b ...