一、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(单例对象和伴生类)的更多相关文章

  1. Scala单例对象、伴生对象实战详解

    1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...

  2. 010-Scala单例对象、伴生对象实战详解

    010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被 ...

  3. Scala单例对象和伴生对象

    1.Scala单例对象 Scala单例对象是十分重要的,没有像在Java一样,有静态类.静态成员.静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员. ...

  4. 【scala】类的定义和单例对象

    一.类的定义 Scala类的定义跟JAVA中类的定义基本是一样的. 示例 class ChecksumAccumulator{ var sum = 0;//Scala默认关键字为public priv ...

  5. scala学习手记14 - 单例对象

    java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例.在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可.因为单例类无法初始化,所以不能向它的主构造函数传 ...

  6. 探索Scala(3)-- 单例对象

    研究一下Scala语言的单例对象(Singleton Objects),为下一篇文章做准备. static不是keyword 上一篇文章提到过,interface并非Scala语言keyword,能够 ...

  7. apply 伴生对象 单例对象

    apply(): 当类或者对象有一个主要用途时,apply方法提供了很好语法机制 scala> class Foo {} defined class Foo scala> object F ...

  8. Scala 孤立对象和单例对象方法体的用法和例子

    [学习笔记] 1  以object关键字修饰一个类名,这种语法叫做孤立对象,这个对象是单例的. 相当于将单例类和单例对象同时定义.相当于java中的单例,即在内存中只会存在一个Test3实例.创建一个 ...

  9. Kotlin入门(18)利用单例对象获取时间

    前面介绍了,使用扩展函数可以很方便地扩充数组Array的处理功能,例如交换两个数组元素.求数组的最大元素等等.那么除了数组之外,日期和时间的相关操作,也是很常见的,比如获取当前日期,获取当前时间.获取 ...

随机推荐

  1. 为FreeBSD安装adobe flash插件

    参考 FreeBSD官方手册浏览器一章. pkg install nspluginwrapper nspluginwrapper 是一个辅助安装配置 NetScape Plugin的工具. 可以为Ne ...

  2. 微服务深入浅出(1)-- SpringBoot

    基于Spring的开发框架,旨在简化配置快速开发,是新一代web开发框架.下面介绍一下常用的几个功能: 1.Spring单元测试 针对DAO层 (1) @RunWith(Spring.class),表 ...

  3. CodeForces 714A

    Description Today an outstanding event is going to happen in the forest — hedgehog Filya will come t ...

  4. POJ 2438 Children’s Dining (哈密顿图模板题之巧妙建反图 )

    题目链接 Description Usually children in kindergarten like to quarrel with each other. This situation an ...

  5. php登陆界面刷新验证码 javascript 的写法

    <script type="text/javascript"> function refreshVerify(){ var imgId = document.getEl ...

  6. Struts2笔记3--获取ServletAPI和OGNL与值栈

    获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.getConte ...

  7. Struts2笔记2--动态方法调用和Action接收请求方式

    动态方法调用(在请求的时候,再明确具体的响应方法,配置的时候不明确): LoginAction类中有两个方法some和second 1. 动态方法的调用(修改常量struts.enable.Dynam ...

  8. Wannacry样本取证特征与清除

    一.取证特征 1)网络域名特征 http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com 2)文件特征 母体文件 mssecsvc.exe c: ...

  9. int、long、long long取值范围

    unsigned   int   0-4294967295 int   -2147483648-2147483647 unsigned long 0-4294967295 long   -214748 ...

  10. aarch64_g4

    golang-github-inconshreveable-muxado-devel-0-0.7.gitf693c7e.fc26.noarch.rpm 2017-02-11 16:47 30K fed ...