Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
单例作为Scala中的合成类?_Scala - Fatal编程技术网

单例作为Scala中的合成类?

单例作为Scala中的合成类?,scala,Scala,我正在读Scala编程,我不理解下面的句子(pdf第112页): 每个单例对象都实现为从 静态变量,因此它们与Java静态具有相同的初始化语义 这是否意味着如果在scala中有一个单例FooBar,编译器将创建一个名为FooBar$的类 作者所说的“从静态变量引用”是什么意思?是否有一个隐藏的静态变量存放着对某个FooBar$类的引用 非常感谢您的帮助。您基本上是对的 如果你有单身汉 object Singleton { def method = "Method result" } 那么编

我正在读Scala编程,我不理解下面的句子(pdf第112页):

每个单例对象都实现为从 静态变量,因此它们与Java静态具有相同的初始化语义

这是否意味着如果在scala中有一个单例FooBar,编译器将创建一个名为FooBar$的类

作者所说的“从静态变量引用”是什么意思?是否有一个隐藏的静态变量存放着对某个FooBar$类的引用


非常感谢您的帮助。

您基本上是对的

如果你有单身汉

object Singleton {
  def method = "Method result"
}
那么编译给你

Singleton.class
Singleton$.class
对于您找到的字节码,首先对于
Singleton

public final class Singleton extends java.lang.Object{
public static final java.lang.String method();
  Signature: ()Ljava/lang/String;
  Code:
   0:   getstatic   #11; //Field Singleton$.MODULE$:LSingleton$;
   3:   invokevirtual   #13; //Method Singleton$.method:()Ljava/lang/String;
   6:   areturn
}
也就是说,类中引用名为
Singleton$.MODULE$
的对象的每个方法都有一个公共静态方法,在
Singleton$
中:

public final class Singleton$ extends java.lang.Object implements scala.ScalaObject{
public static final Singleton$ MODULE$;
  Signature: LSingleton$;

public static {};
  Signature: ()V
  Code:
   0:   new #9; //class Singleton$
   3:   invokespecial   #12; //Method "<init>":()V
   6:   return


public java.lang.String method();
  Signature: ()Ljava/lang/String;
  Code:
   0:   ldc #16; //String Method result
   2:   areturn


private Singleton$();
  Signature: ()V
  Code:
   0:   aload_0
   1:   invokespecial   #20; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   putstatic   #22; //Field MODULE$:LSingleton$;
   8:   return
}
public final类Singleton$extends java.lang.Object实现scala.ScalaObject{
公共静态最终单例$MODULE$;
签署:伦敦元;
公共静态{};
签字:()五
代码:
0:new#9;//单例类$
3:invokespecial#12;//方法“”:()V
6:返回
public java.lang.String方法();
签名:()Ljava/lang/String;
代码:
0:ldc#16;//字符串方法结果
2:轮到你了
私人单身人士$();
签字:()五
代码:
0:aload_0
1:invokespecial#20;//方法java/lang/Object。”“:()V
4:aload_0
5:putstatic#22;//字段模块$:LSingleton$;
8:返回
}
您可以看到,
MODULE$
保存了
Singleton$
的实例,而
method
只是一个普通的方法


所以,这就是它真正的意义所在:使用名为
MODULE$
的静态字段创建
Singleton$
,以保存其自身的唯一实例,填充该字段,然后使用静态方法创建一个
Singleton
,该静态方法将所有静态调用转发到
Singleton$

的相应方法。同样的“Scala编程”的第31章更为精确:

Java没有完全等同于单例对象,但它有静态方法

单例对象的Scala转换使用静态方法和实例方法的组合对于每个Scala singleton对象,编译器将为该对象创建一个Java类,并在末尾添加一个美元符号
对于名为
App
的单例对象,编译器生成名为
App$
的Java类
此类包含Scala singleton对象的所有方法和字段。
Java类还有一个名为
模块$
的静态字段来保存该字段 在运行时创建的类的实例。
作为完整示例,假设您编译以下单例对象:

Scala将生成包含以下字段和方法的Java App$类:

这是一般情况的翻译


是的,我想你理解它了。:-(我不知道,我只是猜了一下!诀窍是静态变量引用实例,而不是类。换句话说,Scala对象
FooBar
在Java中是作为
FooBar$.MODULE$
引用的。谢谢你这么说。我想我应该在书中向前跳过:-)
publicstatic{}的目的是什么
?@Christopherry
静态{}
是一个静态初始化块,用于初始化单例。例如,你看,或者谢谢,这有点清楚,但是数字0 1 4等等是什么?对不起,我不太熟悉字节码lol:(在左边,它们是字节码地址。基本上是行号。在右边,它们指的是类、方法、字段或其他合适的表。
object App {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}
$ javap App$
public final class App$ extends java.lang.Object
    implements scala.ScalaObject{
  public static final App$ MODULE$;
  public static {};
  public App$();
  public void main(java.lang.String[]);
  public int $tag();
}