2017-06-17 11 views
0

私は現在、Fedora 25 OpenJDK 8とKotlin 1.1を使っているKotlinを学んでいます。Kotlin Reflection operator get implementation

この例をKotlinのWebサイト(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'のgetterを呼び出します。達成したいのは何ですか? – nhaarman

+0

私はそれが当てはまると思う、私はリフレクション/委任を介してゲッターを実装するのに役立つ必要があります。 – Malkaviano

答えて

2

Translation Ruleは言う:例えば

を、プロパティのprop隠しプロパティprop$delegateを生成し、この追加のプロパティを単にアクセッサのコード(ゲッター/セッター)委任されています。

のでkotlin プロパティdelegatorゲッター/セッターを派遣します。 get/setデリゲートハンドラ(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

さて、私は間違った角度からこの例に近づきました。それはクラスを国外に保つ方法を示すことを意図していますか?リポジトリなどの構築デリゲート状態にアクセスするというこの固定された考え方が本当にありました。今、それはほとんど意味がないと明確に考えています。 – Malkaviano

+0

@Malkavianoいいえ、大丈夫です。 'Delegate'を実装する方法を決めることができます。 –

+0

コメントを編集できません。翻訳ミスをしました。 「固定されたアイデア」とは、私が硬い思考を意味していたことです – Malkaviano