【问题标题】:Using companion object to return an instance of the class in Kotlin在 Kotlin 中使用伴生对象返回类的实例
【发布时间】:2017-10-25 17:34:45
【问题描述】:
Android Studio 3.0 RC2
Kolin 1.1.51

我创建了一个 Android 应用程序,我想返回扩展 Application 的类的实例,并访问您在 Java 中使用 static 所做的等价物。

class BusbyMoviesMainApplication : Application() {
    companion object {
        private val instance: BusbyMoviesMainApplication = BusbyMoviesMainApplication()

        @JvmStatic
        fun getBusbyInstance(): BusbyMoviesMainApplication {
            return instance
        }
    }
}

我正在像这样访问它。但是,getCacheDir 返回 null

BusbyMoviesMainApplication.getBusbyInstance().getCacheDir()

我看不出我做错了什么。

在 Java 中我以前做过这样的事情,这很有效,我正在尝试在 Kotlin 中做同样的事情:

public class BusbyMoviesApplication extends Application {
    private static BusbyMoviesApplication mBusbyMoviesApplication;

    public static BusbyMoviesApplication getInstance() {
        return mBusbyMoviesApplication;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mBusbyMoviesApplication = BusbyMoviesApplication.this;
    }
}

【问题讨论】:

    标签: java android kotlin


    【解决方案1】:

    在 Kotlin 代码中,您直接调用 Application 子类的构造函数,而不是让框架为您创建它。您可以改为执行您在 Java 代码中所做的操作,并在 ApplicationonCreate 方法中初始化 instance 属性(另外我将 getter 缩短了一点):

    class BusbyMoviesMainApplication : Application() {
        companion object {
            private lateinit var instance: BusbyMoviesMainApplication
    
            @JvmStatic
            fun getBusbyInstance() = instance
        }
    
        override fun onCreate() {
            super.onCreate()
            instance = this
        }
    }
    

    根据下面 cmets 中的讨论,这可能是 getter 更惯用的解决方案:

    class BusbyMoviesMainApplication : Application() {
        companion object {
            @JvmStatic
            lateinit var instance: BusbyMoviesMainApplication
                private set
        }
    
        override fun onCreate() {
            super.onCreate()
            instance = this
        }
    }
    

    【讨论】:

    • 你为什么要显式生成 setter 而不是让 kotlin 为你生成呢?
    • 这是维护 Java 兼容性并让 Java 代码以BusbyMoviesMainApplication.getBusbyInstance() 访问实例的最简单方法。我认为这是问题中的@JvmStatic 所必需的。当然,如果你只使用 Kotlin,你可以将 instance 属性设为 public 并去掉 getter,然后以 BusbyMoviesMainApplication.instance 的身份访问它。
    • Kotlin 无论如何都会生成 getter。对于java interop,可以公开,加上@JvmStatic注解,得到getInstance()方法
    • 你说得对,我避免这样做是因为它也会生成一个 setter,因为 lateinit 属性总是必须是 var 才能分配。我刚刚意识到这可以通过private set 解决。我稍后会编辑答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    相关资源
    最近更新 更多