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类只是作为一个入口。