具有委托属性的类的toString重写限制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有委托属性的类的toString重写限制相关的知识,希望对你有一定的参考价值。

我是Kotlin的新手,我正在尝试自定义委托属性的文档中的示例。

https://try.kotlinlang.org/#/Examples/Delegated%20properties/Custom%20delegate/Custom%20delegate.kt

通常在重写toString方法时,我会像所提供的代码一样限制要打印的字段。

在这种情况下,p是延迟的属性,我们在getValue()字符串中使用thisref。因此,这里由于递归调用而产生了堆栈溢出的问题。

class Example {
    var p: String by Delegate()
    var q: String = "testQ"

    override fun toString() = "Example[p=$p]"
}

class Delegate() {
    operator fun getValue(thisRef: Any?, prop: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${prop.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {
        println("$value has been assigned to ${prop.name} in $thisRef")
    }
}

由于委托属性是针对公共库的,因此应该遵循toString()重写方法的任何限制。

答案

问题不是委托,而是递归:

  1. Example.toString()被称为
  2. Delegate.getValue()由$p调用。 Example的一个实例传递给getValue。
  3. Example.toString()由$thisRef调用。因此它循环回到步骤1!

您可以通过这个非常简单的示例重现该内容:

fun main() {
    class SimpleExample {
        override fun toString() = "$this"
    }

    println(SimpleExample())
}

为了修复它,从$thisRef功能中删除getValue

另一答案
return "$thisRef ... "

在上面您想调用thisRef.toString()(在字符串模板中toString被隐式调用)。然后尝试执行以下行:"Example[p=$p]"。因此,它尝试再次调用thisRef.toString(),而我们再次处于"Example[p=$p]"调用中。

它会说这完全是预期的行为。那你能做什么?不要在委托中使用$thisRef;)

以上是关于具有委托属性的类的toString重写限制的主要内容,如果未能解决你的问题,请参考以下文章

重写Object.toString()总结

Object类

toString( )

面向对象--继承和重写

始终重写 toString 方法

bean通过反射重写toString