伴生类和伴生对象
1.什么叫做伴生?
在两个scala源文件中分别声明:
object User{
}
class Emp{
}
我们可以从编译后生成的字节码文件中看到,object声明的类会编译成两个字节码文件,伴生类和伴生对象是指这种伴随生成的;而对于用class声明的类,不会生成单例对象,因此也不存在伴生的概念,就是普通类;
2.什么是伴生类和伴生对象?
其实这要分为两种场景:
场景1:一个scala文件中,只定义了Object类
- 如果在代码中只定义伴生对象,会自动编译生成伴生类的.class文件
那么生成的两个字节码文件中,带$
的是伴生对象类的字节码文件;不带$
的是伴生类的字节码文件;代码中是看不到伴生类的,但编译后是有的
场景2:一个scala文件中,定义了object和class类
注意: 定义的 class 与 object 必须在同一个文件内
- class 称为伴生类,将非静态的内容写到该类中
- object 称为伴生对象,将静态的内容写入到该对象(类)
教材中关于伴生对象的解释是:实现类似 Java 中那种既有实例成员又有静态成员的类的功能
3.二者反编译java类的区别
通过java Decompiler工具可以将字节码文件反编译成java代码;
(1) object User 生成的两个字节码文件
1.User.class文件
public final class User
{
}
2.User$.class文件
public final class User$
{
public static MODULE$;
static
{
new ();
}
private User$()
{
MODULE$ = this;
}
}
(2) class Emp
public class user {
}
-
如果只声明伴生对象,反编译的两个类都是
public final
的;(如上面的object User所示) -
如果声明了class,那么伴生类反编译的类没有
final
修饰; -
伴生对象的反编译类中对构造器进行了私有化,只对外提供了一个静态属性
MODULE$
,作为此类创建的对象
4.伴生对象和伴生类的功能
1.伴生类中属性和方法都是非静态的,必须通过实例对象来访问
2.伴生对象中的属性和方法都是静态的,可以通过类名来访问
object AccompanyObject {
def main(args: Array[String]): Unit = {
println(ScalaPerson.sex)
ScalaPerson.sayHi()
}
}
//伴生类
class ScalaPerson {
//
var name : String = _
}
//伴生对象
object ScalaPerson {
//
var sex:</