Kotlin-Object关键字作用
2022-03-31 本文已影响0人
杨0612
Object关键字使用场景:匿名内部类、单例、伴生对象。
匿名内部类
Kotlin匿名内部类定义使用跟Java类似,如何定义这里就不多赘述了。
不过它有一个增强的点,Java的匿名内部类不能再继承接口,而Kotlin可以。
以下匿名内部类在实现I1接口的基础上,再实现I2、 I3两个接口,相当于增强能力。被监听者根据不同场景进行回调,例如某场景只需要回调I1,某场景需要回调I2、I3。
Java要实现此功能,需要定义一个内部类,Kotlin会比较灵活一些。
fun test() {
val listener = object : I1, I2, I3 {
override fun onSuccess1() {}
override fun onSuccess2() {}
override fun onSuccess3() {}
}
setListener(listener)
}
private fun setListener(listener: I1) {
//dosomething
listener.onSuccess1()
if (listener is I2) {
listener.onSuccess2()
}
if (listener is I3) {
listener.onSuccess3()
}
}
单例
Kotlin实现单例是非常简单的,只要用object描述类名即可。
object A {
fun test(){}
}
//反编译代码
public final class A {
@NotNull
public static final A INSTANCE;
public final void test() {}
private A() {}
static {
A var0 = new A();
INSTANCE = var0;
}
}
看了下反编译的代码,原来是在类A初始化的时候就创建实例了。
不过这种方式有两个问题
- 可能会浪费性能,因为在没有使用就已经创建了;
- 无法传入参数,对于Android平台是很不友好的。
伴生对象
伴生对象是类中的静态对象,只能内部实例化且只有一个,可以用来定义类的静态变量、函数。
class A {
companion object {
const val name: String = "A"//1
fun getInstance(): A {//2
return A()
}
}
}
- 注释1,定义了静态变量name;
- 注释2,定义了静态方法getInstance获取实例对象;
反编译看看
public final class A {
@NotNull
public static final String name = "A";//1
@NotNull
public static final A.Companion Companion = new A.Companion();//2
public static final class Companion {//3
@NotNull
public final A getInstance() {//5
return new A();
}
private Companion() {//4
}
public Companion(DefaultConstructorMarker $constructor_marker) {//6
this();
}
}
}
- 注释1,对应companion object{}中定义的静态变量name;
- 注释2、3、4,定义了静态内部类Companion,且构造函数是私有,A实例化了静态变量Companion;
- 注释5,对应companion object{}中定义的静态函数getInstance;
- 注释6,虽然也定义了public构造函数,但观察入参类型得知,该构造函数只能是编译器调用,而我们开发者是无法调用的。
所以我们知道,Kotlin的companion object{},是对应一个对象,也叫伴生对象,
该对象类会描述我们定义的静态函数(静态变量好像不属于该类)。
一个有意思的细节
class A {
companion object {
const val name: String = "A"
@JvmStatic//1
fun getInstance(): A {
return A()
}
}
}
//加注解前,Java调用
B.Companion.getInstance();
//加注解后,Java调用
B.getInstance();
- 注释1:增加@JvmStatic注解是为了方便Java调用,那么反编译以后A中会增加定义getInstance函数,不过其内部还是调用伴生对象的getInstance。
大家可以反编译看看。
以上分析有不对的地方,请指出,互相学习,谢谢哦!