一、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. 【学习DIV+CSS】2. 学习CSS(一)--CSS控制页面样式

    1. CSS如何控制页面 使用XHTML+CSS布局页面,其中有一个很重要的特点就是“结构与表现相分离”(结构指XHTML,表现指CSS).有人这样描述这种分离的关系,结构XHTML好比一个人,表现C ...

  2. Document对象中的一些重要的属性和方法(笔记)

    Document对象:每一个web浏览器窗口.标签页和框架由一个window对象所表示.每个window对象都有一个document属性引用的是Document对象,它是一个巨大的API中的核心对象, ...

  3. 《PHP和MySQL Web开发》读书笔记(上篇)

    最近过得太浮躁了,实在自己都看不下去了,看了PHP圣经之后,觉得非常有必要要总结一下. Chapter1.快速入门 ·PHP标记:总共有三种风格,常用的还是XML风格为主 <?php echo ...

  4. Javascript实现返回上一页面并刷新

    今天写了一个小小的提示成功的页面,同时要求返回上一页面,并实现对上一页面的操作进行刷新(例如删除的,添加的),在网上搜寻了一遍,基本上90%的都是说的是用window.history.go(-1), ...

  5. 05.UIDynamic

    CHENYILONG Blog 05.UIDynamic Fullscreen © chenyilong. Powered by Postach.io Blog

  6. SpringBoot与异步任务、定时任务、邮件任务

    异步任务 在需要开启异步的服务加上注解:@Async @Service public class AsyncService { //告诉SpringBoot这是一个异步任务,SpringBoot会自动 ...

  7. C++中的二级指针和指针引用函数传参

    在函数的使用过程中,我们都明白传值和传引用会使实参的值发生改变.那么能够通过传指针改变指针所指向的地址吗? 在解决这个问题之前,也许我们应该先了解指针非常容易混淆的三个属性: ①.指针变量地址(&am ...

  8. ASP.NET MVC 防止跨站请求伪造(CSRF)攻击的方法

    在HTTP POST请求中,我们多次在View和Controller中看下如下代码: View中调用了Html.AntiForgeryToken(). Controller中的方法添加了[Valida ...

  9. HTTP之一 If-Modified-Since & If-None-Match

    If-Modified-Since & If-None-MatchIf-Modified-Since,和 Last-Modified 一样都是用于记录页面最后修改时间的 HTTP 头信息,只是 ...

  10. 28 Data Race Detector 数据种类探测器:数据种类探测器手册

    Data Race Detector 数据种类探测器:数据种类探测器手册 Introduction Usage Report Format Options Excluding Tests How To ...