android - Kotlin 中对象/私有(private)构造函数/伴生对象之间的区别?

标签 android kotlin

请不要怪我。我刚刚从 Java 迁移到 Kotlin。我尝试在 Singleton.getInstance().someMethod() 的帮助下以常规 java 方式创建单例,并发现在 Kotlin 中您可以使用几种不同的东西:

对象(单独的文件)对象单例

伴随对象伴随对象工厂{}

私有(private)构造函数 类单例私有(private)构造函数()

您能帮我解释一下我们可以在哪里输入什么类型吗?

最佳答案

Kotlin 中的对象就像 Java 中的静态类。它们通常用于构造单例模式:

object Singleton

Java 中的等价物是:

public static class Singleton{}

伴生对象用于必须应用工厂模式或静态工厂模式的情况(如伴生对象名称所示)。

假设我们在 Java 中有这个:

public class Fragment(){
  private Fragment(){}

  public static Fragment newInstance(){
    return new Fragment();
  }
  
}

Kotlin 中的等价物是:

class Fragment private constructor(){
  companion object{
    fun newInstance() = Fragment()
  }
}

伴生对象也是一个对象,但是通过伴生这个词只是告诉JVM这个对象所在的类,可以访问其中的所有内容。

因此,如果您尝试从 Java 代码中调用它,它将是这样的:

Fragment.Companion.newInstance()

上面的例子实际上也适合私有(private)构造函数。 基本上,即使在 Java 中,当您不需要直接访问构造函数时,只需将构造函数标记为私有(private)并使用静态工厂方法即可。

关于您的问题,根据上面提供的信息:

实现

Singleton.getInstance().someMethod()

对于这个调用,您必须执行以下操作:

class Singleton private constructor(){
  companion object{
    fun getInstance() = Singleton()
    fun someMethod(){ /* Your implement here */}
  }
}

然而,这在 Kotlin 风格中并不太复杂。

就这样做:

object Singleton{
    fun someMethod(){ /* Your method here */}
}

然后调用它:

Singleton.myMethod()

编辑:关于您的 SharedPreferences 问题,我不建议为此使用 object 。您需要上下文的构造函数,也许还需要共享首选项模式。因此,我会选择这样的东西(假设您正在使用 Dagger ,因为您在评论中提到了它):

class SharedPreferencesHelper @Inject constructor(val context: Context, val mode: Int) // not sure about the mode type but check the docs {

    private lateinit var sharedPreferences: SharedPreferences
    private lateinit var sharedPreferencesEditor: SharedPreferences.Editor

    init{
        sharedPreferences = context.getSharedPreferences("filename", mode)
        sharedPreferencesEditor = sharedPreferences.edit()
    }
    
}

然后你只需在任何需要的构造函数中调用它即可。

或者:

class SharedPreferencesHelper private constructor(){
    private lateinit var sharedPreferences: SharedPreferences
    private lateinit var sharedPreferencesEditor: SharedPreferences.Editor
    
    companion object {
        fun startSharedPrefs(context: Context, fileName: String, mode: Int) = SharedPreferencesHelper().apply{
         sharedPreferences = context.getSharedPreferences(fileName, mode)
         sharedPreferencesEditor = sharedPreferences.edit()
        }
    }

}

然后在 dagger 模块中启动它:

@Module
object SharedPrefsModule{
    @Singleton
    @Provides
    fun provideSharedPreferences(application: Application) = 
     SharedPreferencesHelper.startSharedPrefs(application, "fileName", MODE_PRIVATE)

}

然后在需要的地方调用依赖项

关于android - Kotlin 中对象/私有(private)构造函数/伴生对象之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62561566/

相关文章:

android - 如何理解android根树的目录结构?

kotlin - 是否有一种标准的 Kotlin 方法可以使数据类的这个特殊情况对象具有不同的 toString() 方法?

kotlin - 如何以不区分大小写的顺序对对象列表进行排序?

java - 如何在android中创建多语言应用程序

java - run() 方法内的时间

android - 静态图像中的颜色检测 - OpenCV Android

android - 任务:react-native-camera:compileGeneralDebugJavaWithJavac FAILED

android - 可以在 UI 线程上查询 DownloadManager 吗?

java - 有没有办法从单个类创建多个 @Client bean

android - MVP Presenter 未正确注入(inject)