2017-06-17 72 views
0

我正在学习Kotlin,目前使用Fedora 25 OpenJDK 8和Kotlin 1.1。Kotlin Reflection运算符得到实现

我复制了Kotlin网站的示例:https://kotlinlang.org/docs/reference/delegated-properties.html并更改了get运算符。

class Example { 
var p: String by Delegate() 
} 

class Delegate { 
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String { 
     // My implementation 
     return property.getter.call(thisRef) as String 
    } 

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

阅读反思文档,吸气预计的对象实例,并没有其他的参数,但我只取得了以下错误。 (错误的缩写,因为它太大了,它在递归。)

. 
. 
. 
at info.malk.Example.getP(Delegation.kt) 
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at kotlin.reflect.jvm.internal.FunctionCaller$Method.callMethod(FunctionCaller.kt:98) 
at kotlin.reflect.jvm.internal.FunctionCaller$InstanceMethod.call(FunctionCaller.kt:115) 
at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:107) 
at info.malk.Delegate.getValue(Delegation.kt:32) 
at info.malk.Example.getP(Delegation.kt) 
. 
. 
. 
Caused by: java.lang.reflect.InvocationTargetException 
    ... 1024 more 
Caused by: java.lang.StackOverflowError 
    ... 1024 more 

Process finished with exit code 1 

帮助。

+0

您递归调用了'p'吸气。你想达到什么目标? – nhaarman

+0

我怀疑是这种情况,我想通过反射/委派来实现getter的帮助。 – Malkaviano

回答

2

Translation Rule说:

例如,对于属性prop生成隐藏属性prop$delegate,和存取器的代码(的getter/setter)简单地代表该附加属性。

所以科特林财产将派遣的getter/setterdelegator。当你在得到/设置属性的值在代理处理程序(getValue/setValue)左右会导致递归调用。

Delegate更应该是这样的:

class Delegate<T> { 

    private var value: T? = null; 
    //   ^--- store the proeprty value internal 

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T { 
     return value ?: throw UninitializedPropertyAccessException(); 
    } 

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { 
     this.value = value; 
    } 
} 
+0

好吧,我从错误的角度来看这个例子,它的目的是展示如何保持Class以外的状态?就像构建一个Repository或其他东西一样。我确实有了访问委托人状态的固定想法,现在认为这显然没有意义。 – Malkaviano

+0

@Malkaviano不是所有的权利。你可以决定如何实现'Delegate'。 –

+0

无法编辑我的评论,我犯了翻译错误。 “固定的想法”是指僵硬的思维。 – Malkaviano