单例模式在Scala中就是一个默认实现的模式。 对于Java中的单例模式,请看http://www.ivanpig.com/blog/?p=75。 虽然从代码上看,单例模式很简单。但是涉及到多线程问题,问题会很复杂。 Scala中完全不用担心这个问题。
object Single{ def say(){ println("Hello") } def main(args : Array[String]){ Single.say() Single.say() } }
搞定。乍一看怎么也不像是单例模式,更像是静态方法的调用。我们来看一下这段代码实际的执行流程就明白了
scalac Single.scala javap -verbose Single$
这里在反编译的是Single 而不是Single,是因为scalac编译生成了Single.class和Single .class这两个文件。而实际代码在Single$.class中,Single.class只是对Single$.class的一个调用。 反编译得到
...... { public static final Single$ MODULE$; public static {}; Code: Stack=1, Locals=0, Args_size=0 0: new #2; //class Single$ 3: invokespecial #12; //Method "<init>":()V 6: return public void say(); Code: Stack=2, Locals=1, Args_size=1 0: getstatic #18; //Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc #20; //String Hello 5: invokevirtual #24; //Method scala/Predef$.println:(Ljava/lang/Object;) V 8: return LocalVariableTable: Start Length Slot Name Signature 0 9 0 this LSingle$; LineNumberTable: line 6: 0 public void main(java.lang.String[]); Code: Stack=1, Locals=2, Args_size=2 0: aload_0 1: invokevirtual #29; //Method say:()V 4: aload_0 5: invokevirtual #29; //Method say:()V 8: return LocalVariableTable: Start Length Slot Name Signature 0 9 0 this LSingle$; 0 9 1 args [Ljava/lang/String; LineNumberTable: line 10: 0 line 11: 4 }
从这里我们就可以看出上面这段Scala代码所对应的Java代码了。 首先,有一个Single$类型的static final的对象。并且有一个静态化块来初始化它。所以只有在第一次调用时才会实例化此对象。在main方法中只是简单的调用而已。
Blog URL : http://www.ivanpig.com/blog/?p=523