読者です 読者をやめる 読者になる 読者になる

ゲンゾウ用ポストイット

Java、Groovy、Linux関連の備忘録

MetaClassを使用したクラスの拡張は、インスタンス生成前に行わないといけない??

型に対するメタクラスインスタンスに対するメタクラスで遊んでたら例外がでた - お だ のスペース <http://d.hatena.ne.jp/odashinsuke/20091003/1254553781>
にて知りました。

以下のようにあるクラスのインスタンス生成後に、メタクラスによるメソッドを追加を行ってみる。

class Test {
    void methodA() {
        println 'Print'
    }
}

def t = new Test()
Test.metaClass.methodA = { println 'Class Custom Print' }
t.methodA()
new Test().methodA()
t.methodA()

適用されるのは拡張後にインスタンス生成された10行目の処理のみになる。
おださんは、8行目のクラス拡張後にインスタンスの拡張も実施してみたみたいです。

class Test {
    void methodA() {
        println 'Print'
    }
}

def t = new Test()
Test.metaClass.methodA = { println 'Class Custom Print' }
t.methodA()
new Test().methodA()
t.metaClass.methodA = { println 'Instance Custom Print' }
t.methodA()

たしかに11行目のインスタンス拡張処理部分で落ちます。
なぜ???
ただしこれも7行目、8行目の処理を入れ替えると動作します。

class Test {
    void methodA() {
        println 'Print'
    }
}

Test.metaClass.methodA = { println 'Class Custom Print' }
def t = new Test()
t.methodA()
new Test().methodA()
t.metaClass.methodA = { println 'Instance Custom Print' }
t.methodA()

あるインスタンスに対して拡張を行なった後に(上の例では変数t)、クラス拡張を行ってはダメみたいです。
これは仕様なのかな??