Какой из них лучший объект или верхняя функция в Котлине?

Я добавил некоторую полезность в Tool.kt, и метод A, и метод B могут работать хорошо.

Я думаю, что метод B будет храниться в памяти при запуске приложения, даже если я никогда не вызываю fun <T> preference(context: Context, name: String, default: T)

Я думаю, что метод А выделяет память только при вызове DelegatesExt.preference(this,"ZipCode",100L)

Поэтому я считаю, что метод А лучше метода В, верно?

Способ A

 object DelegatesExt { fun <T> preference(context: Context, name: String, default: T) = Preference(context, name, default) } class Preference<T>(private val context: Context, private val name: String, private val default: T) { private val prefs: SharedPreferences by lazy { context.getSharedPreferences("default", Context.MODE_PRIVATE) } operator fun getValue(thisRef: Any?, property: KProperty<*>): T = findPreference(name, default) operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { putPreference(name, value) } @Suppress("UNCHECKED_CAST") private fun findPreference(name: String, default: T): T = with(prefs) { val res: Any = when (default) { is Long -> getLong(name, default) is String -> getString(name, default) is Int -> getInt(name, default) is Boolean -> getBoolean(name, default) is Float -> getFloat(name, default) else -> throw IllegalArgumentException("This type can be saved into Preferences") } res as T } @SuppressLint("CommitPrefEdits") private fun putPreference(name: String, value: T) = with(prefs.edit()) { when (value) { is Long -> putLong(name, value) is String -> putString(name, value) is Int -> putInt(name, value) is Boolean -> putBoolean(name, value) is Float -> putFloat(name, value) else -> throw IllegalArgumentException("This type can't be saved into Preferences") }.apply() } } 

Способ B

 fun <T> preference(context: Context, name: String, default: T) = Preference(context, name, default) class Preference<T>(private val context: Context, private val name: String, private val default: T) { private val prefs: SharedPreferences by lazy { context.getSharedPreferences("default", Context.MODE_PRIVATE) } operator fun getValue(thisRef: Any?, property: KProperty<*>): T = findPreference(name, default) operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { putPreference(name, value) } @Suppress("UNCHECKED_CAST") private fun findPreference(name: String, default: T): T = with(prefs) { val res: Any = when (default) { is Long -> getLong(name, default) is String -> getString(name, default) is Int -> getInt(name, default) is Boolean -> getBoolean(name, default) is Float -> getFloat(name, default) else -> throw IllegalArgumentException("This type can be saved into Preferences") } res as T } @SuppressLint("CommitPrefEdits") private fun putPreference(name: String, value: T) = with(prefs.edit()) { when (value) { is Long -> putLong(name, value) is String -> putString(name, value) is Int -> putInt(name, value) is Boolean -> putBoolean(name, value) is Float -> putFloat(name, value) else -> throw IllegalArgumentException("This type can't be saved into Preferences") }.apply() } } 

    Я думаю, что метод B будет храниться в памяти, когда я запустил приложение, даже если я никогда не вызываю fun <T> preference(context: Context, name: String, default: T)

    1. Что именно он сохранит в памяти?

    2. Нет, методы одинаковы, кроме использования при вызове в Котлин. Но на самом деле, preference метода B находится внутри класса ToolKt которое вы можете увидеть, если попытаетесь вызвать его из Java.

    3. Зачем определять одну из функций preference вместо прямого использования конструктора Preference ? Конструкторы Kotlin не имеют проблем с выводами типа, такими как Java.

    Метод A будет выделять object DelegatesExt во время инициализации статического класса – как только вы ссылаетесь на DelegatesExt в своем коде, потому что object в Kotlin является singleton с ленивой инициализацией.

    Затем, когда вы назовете DelegatesExt.preference(...) , он выделит ваш объект Preference<T> . Кстати, он будет выделять новый экземпляр для каждого вызова, что не является хорошей идеей.

    Затем, когда вы getValue или setValue , будут выделены SharedPreferences (один раз только для экземпляра Preference<T> ).

    Метод B не выделяет избыточный object DelegatesExt , а Preference<T> также будет выделен для каждого вызова метода. Это будет скомпилировано для эффективного использования того же кода, что и класс со статическим методом в Java.

    Но Preference<T> не будет выделено перед вызовом метода preference (в обоих случаях).

    Короче говоря, оба варианта почти одинаковы, за исключением object DelegatesExt который выделяется или нет. Но стоит прекратить выделение нового Preference<T> для каждого вызова метода preference .