哪一个是Kotlin中更好的对象或顶级函数?
我在Tool.kt中加入了一些实用工具,方法A和方法B都可以正常工作。
我想方法B会保存在内存中,当我启动一个应用程序,即使我从来没有调用fun <T> preference(context: Context, name: String, default: T)
我想方法A只调用DelegatesExt.preference(this,"ZipCode",100L)
时分配内存
所以我认为方法A比方法B好,对吗?
方法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() } }
我认为即使我从不调用
fun <T> preference(context: Context, name: String, default: T)
-
什么会保留在内存中?
-
不,除了在Kotlin中调用时,方法是相同的。 但事实上,B方法的
preference
级在类ToolKt
,如果您尝试从Java调用它,则可以看到它。 -
为什么定义
preference
函数而不是直接使用Preference
构造函数? Kotlin构造函数不像Java那样有类型推断的问题。
方法A将在静态类初始化期间分配object DelegatesExt
– 只要您在代码中引用了DelegatesExt
,因为Kotlin中的object
是单例式的,且具有延迟初始化。
然后,当你调用DelegatesExt.preference(...)
,它会分配你的Preference<T>
对象。 顺便说一下,它会在每次通话中分配一个新的实例,这不是一个好主意。
然后,当您调用getValue
或setValue
,将分配SharedPreferences
(每个Preference<T>
实例只分配一次)。
方法B不分配一个冗余object DelegatesExt
和Preference<T>
也将在每个方法调用上分配。 这将被编译成与Java中使用静态方法的类相同的代码。
但Preference<T>
不会在preference
方法调用之前分配(在这两种情况下)。
长话短说,两个选项几乎相同,除了被分配的object DelegatesExt
。 但是,在每个preference
方法调用中停止分配新的Preference<T>
是值得的。