前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >11. Kotlin 类声明与伴生对象(companion)

11. Kotlin 类声明与伴生对象(companion)

作者头像
sickworm
发布2020-04-14 21:37:11
2.8K0
发布2020-04-14 21:37:11
举报
文章被收录于专栏:sickworm

1. companion object 的诞生

Scala 说,要有伴生对象。 于是 Kotlin 便有了 companion object。

companion object 的出现是为了解决 Java static 方法的反面向对象(Anti-OOP)的问题。static 方法无法声明为接口,无法被重写——用更学术的话来说,static 方法没有面向对象的消息传递延迟绑定特性[参考]。而 Scala 为了完成一切皆对象的使命,以及提高与 Java 的兼容性,提出了伴生对象这个概念来代替 static 方法。随后出身的 Kotlin 也借鉴了这个概念。

companion 伴生对象是一个对象,它在类初始化时被实例化。 因为伴生对象不再是类的 static 方法,而是某个类的实例化对象,所以它可以声明接口,里面的方法也可以被重写,具备面向对象的所有特点。

2. companion 的实现

在 Kotlin 中,调用 Java 的 static 方法和调用 Kotlin 的 companion object 方法是一样的:

代码语言:javascript
复制
AJavaClass.staticFun()
AKotlinClass.companionFun()

而在 Java 中,调用 static 方法和 Kotlin 的伴生 companion object 方法,有一点不同:

代码语言:javascript
复制
AJavaClass.staticFun();
AKotlinClass.Companion.companionFun();

从 Java 的调用我们可以发现,companion object 的 JVM 字节码体现,是一个声明了一个叫 Companion 的 static 变量。

而 Kotlin 调用一致,其实是编译器的特殊处理的结果。

如果我们反编译AKotlinClass,可以看到:

代码语言:javascript
复制
// AKotlinClass.class
public final class AKotlinClass {
    public static final Companion Companion = new Companion(null);
}
代码语言:javascript
复制
// AKotlinClass$Companion.class
public final class AKotlinClass$Companion {
    private DownloadExecutor$Companion() {
    }

    public /* synthetic */ DownloadExecutor$Companion(DefaultConstructorMarker $constructor_marker) {
        this();
    }

    public final void companionFun() {
    }
}

可以看到,Companion 是一个叫 AKotlinClass$Companion 的类的实例,带 $ 符号表示这个类是 AKotlinClass 的内部类,名字叫 Companion,所以在AKotlinClass中直接new Companion(null)即可。

你也许还留意到实例化 Companion 使用的是一个带 DefaultConstructorMarker 入参的构造器。它出现的场景是,如果是 Kotlin 编译器生成的特殊构造器,就会带这个参数。在这里,Kotlin 希望能够实例化 Companion 类,但又不想声明一个 public 的构造器,于是就声明了这样一个特殊的构造器。DefaultConstructorMarker 值永远为 null。 DefaultConstructorMarker 出现的另一个场景是:带默认参数的构造器。因为带了默认参数后,构造器需要增加 int 类型的 bitmask 入参,来识别哪个入参需要被替换为默认参数。而为构造器增加一个入参,容易和其他构造器“撞车”,即构造器的入参完全一样,导致编译失败。所以默认参数的构造器末尾还会增加一个 DefaultConstructorMarker 入参,来防止构造器参数一致的问题。[参考] 版权所有,转载请注明出处: https://cloud.tencent.com/developer/article/1614343

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年4月12日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. companion object 的诞生
  • 2. companion 的实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档