java 里面的class和Object跟Scala中的class和Object有很大的差别,
首先,java里的class可以指一个编译后的.class文件,也是一个定义类的关键字,scala中的有两种class,一种是一般的class,如果在class前面加上case,那他就是一个final的javabean。
java里面的Object是所有类的父类,而且java里面class实例化后也可以称为一个Object,scala中Object是一个关键字,被Object关键字标注的都是一个单利对象,他是一个final的class,构造器是私有的。
scala中有一个半生类、半生对象的概念,具体对比看代码:
java中的一般类
public class JavaClass { public static void test1() { System.out.println("invoke static method test1"); } public void test2() { System.out.println("invoke method test2"); } } class JavaMainTest { public static void main(String args[]) { JavaClass.test1(); JavaClass javaClass = new JavaClass(); javaClass.test2(); JavaSingletonClass.getInstance().countAdd(1); JavaSingletonClass.getInstance().countAdd(2); JavaSingletonClass.getInstance().countAdd(3); JavaSingletonClass.getInstance().countAdd(4); } }
java中的单利
public class JavaSingletonClass { private static JavaSingletonClass ourInstance = new JavaSingletonClass(); public static JavaSingletonClass getInstance() { return ourInstance; } private int count = 0; private JavaSingletonClass() { } public void countAdd(int num) { count = count + num; System.out.println("Current count:" + count); } }
?scala中的object
object ScalaObject { val parma = "" def oneMethod = println("00000000") }
?编译后可以看到生成了两个class文件,ScalaObject和ScalaObject$两个文件,ScalaObject是对外报漏的对象,ScalaObject$是一个虚构对象。
?反编译后:
public final class ScalaObject { public static void oneMethod() { ScalaObject..MODULE$.oneMethod(); } public static String parma() { return ScalaObject..MODULE$.parma(); } }
?
public final class ScalaObject$ { public static final MODULE$; private final String parma; static { new (); } public String parma() { return this.parma; } public void oneMethod() { Predef..MODULE$.println("00000000"); } private ScalaObject$() { MODULE$ = this;this.parma = ""; } }
?ScalaObject反编译后是两个静态方法,静态方法通过ScalaObject$中的 MODULE$参数分别调用两个方法,ScalaObject$则是一个单利对象,MODULE$则是当前单例对象的一个引用
?
由此可见, 这个虚构类ScalaObject$是单例的。 一方面, 这个类是编译器默认生成的,在Scala代码中无法访问到。 另一方面, ScalaObject$构造器私有了, 只在内部创建了一个对象赋给了静态引用MODULE$ 。?
?
所以, 在Scala里面称用object关键字修饰的对象是单例对象, 在实现的角度上看, 并不是十分确切。 虽然称之为对象, 但是编译器确实为他生成了一个类, 如上面例子中的object ScalaObject?, 编译器确实生成了类ScalaObject。 但是这个类中只有静态方法, 即使是一个Scala中的字段, 也对应一个静态方法, 如上例中的字段a 。 这个类中的静态方法会访问虚构类ScalaObject $中的静态成员ScalaObject $ MODULE$ ,使用这个对象可以调用ScalaObject$中的其他成员方法,Test$中的成员和源码中的成员相对应, 只是会为源码中的字段添加同名方法。 主要的处理逻辑实际上是在虚构类Test$中完成的, ScalaObject类只是作为一个入口。