在哪种情况下,在Kotlin构造函数参数中需要val / var?

时间:2017-08-22 15:39:12

标签: android kotlin

正确的代码:

System.TypeInitializationException : The type initializer for 'Realms.Realm' threw an exception.
  ----> System.DllNotFoundException : realm-wrappers

无法解析代码:

class MainActHandler(val weakActivity: WeakReference<Activity>): Handler() {
    override fun handleMessage(msg: Message?) {
        val trueAct = weakActivity.get() ?: return
        if (msg?.what == ConversationMgr.MSG_WHAT_NEW_SENTENCE){
            val sentence = msg.obj as String?
            trueAct.conversation.text = sentence
        }
        super.handleMessage(msg)
    }
}

cannot be resolved code screenshot

唯一的区别是&#34; val&#34;已被删除,无法解决。

这可能很重要,因为它是一个内在阶层。

BUT

这一课没有&#34; val / var&#34;在构造函数参数中工作:

class MainActHandler(weakActivity: WeakReference<Activity>): Handler() {
    override fun handleMessage(msg: Message?) {
        val trueAct = weakActivity.get() ?: return
        if (msg?.what == ConversationMgr.MSG_WHAT_NEW_SENTENCE){
            val sentence = msg.obj as String?
            trueAct.conversation.text = sentence
        }
        super.handleMessage(msg)
    }
}

}

如果我在&#34; queue:RequestQueue&#34;之前添加var / val,我会得到建议:

&#34; Constructor参数从不用作属性。此检查报告主要构造函数参数,这些参数可以包含&#39; val&#39;或者&#39; var&#39;除去。不必要地使用&#39; val&#39;和&#39; var&#39;在主构造函数中消耗不必要的内存。&#34;

我对此感到困惑。

3 个答案:

答案 0 :(得分:24)

当您在构造函数中编写val / var时,它会在类中声明一个属性。当您不编写它时,它只是传递给主构造函数的参数,您可以在其中访问init块中的参数或使用它来初始化其他属性。例如,

class User(val id: Long, email: String) {
    val hasEmail = email.isNotBlank()    //email can be accessed here
    init {
        //email can be accessed here
    }

    fun getEmail(){
        //email can't be accessed here
    }
}
  

构造函数参数永远不会用作属性

这个建议是说除了初始化之外你不要使用这个属性。因此,它建议您从类中删除此属性。

答案 1 :(得分:5)

构造函数参数在用作类中其他位置的属性时,必须使用varval。如果它们仅用于类初始化,则它们不需要是属性。

在这种情况下,参数必须是属性(varval),因为它在方法中使用:

class A(val number: Int) {
    fun foo() = number
}

在这种情况下,该参数仅用于初始化类,因此它不需要是属性:

class B(number: Int): A(number) {
    init {
        System.out.println("number: $number")
    }
}

答案 2 :(得分:0)

要使@Parcelize 工作,您需要打开超级的属性并在子级中覆盖它们:

abstract class Goal(open var number: Int, open var name: String) : Parcelable

@Parcelize
class OperationalGoal(override var number: Int, override var name: String, var description: String) : Goal(number, name)```