1. Scala中的单例对象编译原理
所有的Scala代码都会被Scala编译器翻译成Java字节码,因为Scala和Java共用JVM(虚拟机)
思考: Scala中 单例对象和伴生对象 的区别?
单例对象: 没有同名的类(伴生类)
伴生对象: 有同名的类(伴生类)
1.1 单例对象编译过程
步骤1: 定义名为 SingleObject 单例对象
// 单例对象
object SingleObject {
def printSql(sql: String) = println(sql)
def main(args: Array[String]): Unit = {
println("Hello Scala!!!")
}
}
步骤2: 使用 scalac 编译 SingleObject.scala
生成下面两个.class文件
SingleObject$.class
SingleObject.class
步骤3: 使用 javap 反编译生成的 .class
bogon:java baidu$ javap SingleObject.class
Compiled from "SingleObject.scala"
public final class com.maven.java.SingleObject {
public static void main(java.lang.String[]);
public static void printSql(java.lang.String);
}
bogon:java baidu$ javap SingleObject$.class
Compiled from "SingleObject.scala"
public final class com.maven.java.SingleObject$ {
public static com.maven.java.SingleObject$ MODULE$;
public static {};
public void printSql(java.lang.String);
public void main(java.lang.String[]);
}
总结:
Scala编译器会为 每个单例对象 创建一个名称+$的java类
这个java类拥有单例对象的所有方法和字段,同时还有一个名为 MODULE$的静态字段
保证这个java类在类加载时期就创建一个实例
如果是单例对象,Scala编译器还会创建一个 和单例对象同名的java类
并且在这个同名类中 将单例对象所有的方法 转为静态方法
1.2 伴生对象编译过程
步骤1: 定义名为 Boby 伴生对象和伴生类
// 伴生类
class Boby(val id:Int,val name:String)
// 伴生对象
object Boby {
def printSql(sql: String) = println(sql)
def main(args: Array[String]): Unit = {
println("Hello Scala!!!")
}
}
步骤2: 使用 scalac 编译 Boby.scala
生成下面两个.class文件
Boby$.class
Boby.class
步骤3: 使用 javap 反编译生成的 .class
bogon:java baidu$ javap Boby$.class
Compiled from "Boby.scala"
public final class com.maven.java.Boby$ {
public static com.maven.java.Boby$ MODULE$;
public static {};
public void printSql(java.lang.String);
public void main(java.lang.String[]);
}
bogon:java baidu$ javap Boby.class
Compiled from "Boby.scala"
public class com.maven.java.Boby {
public static void main(java.lang.String[]);
public static void printSql(java.lang.String);
public int id();
public java.lang.String name();
public com.maven.java.Boby(int, java.lang.String);
}
总结:
Scala编译器会为 每个伴生对象 创建一个名称+$的java类
这个java类拥有伴生对象的所有方法和字段,同时还有一个名为 MODULE$的静态字段
保证这个java类在类加载时期就创建一个实例
如果是伴生对象,Scala编译器还会在伴生类中添加 伴生对象中所有的方法并且转为静态方法