やりたい事は、Java で宣言されているインターフェースとそれを実装したクラスがあって、インターフェースで宣言されている一部のメソッドの実装を差し替えたい。
このコードでうまくいかない。
Impl.java
interface Test { void print(); } public class Impl implements Test { public void print() { System.out.println("impl"); } }GTest.groovy
Impl.metaClass.print = { println "class custom print" } Impl i = new Impl() // i.metaClass.print = { println "instance custom print" } i.print() // 型のメタクラス、インスタンスのメタクラスどちらを使った場合でも "impl" が出力される。
このコードだと、一応うまくいく
Impl.java のコードは上と同じ
GTest.groovyTest.metaClass.print = { println "class custom print" } // インターフェースのメタクラスを使う Impl i = new Impl() i.print() // "class custom impl" が出力される。
でもこれだと Test っていうインターフェースを実装している全てのクラスのメソッドを変更してしまう。
Impl.java のコードは上と同じ
Impl2.javapublic class Impl2 implements Test { public void print() { System.out.println("impl2"); } }GTest.groovy
Test.metaClass.print = { println "class custom print" } Impl i = new Impl() i.print() // "class custom impl" が出力される。 Impl2 i2 = new Impl2() i2.print() // "class custom impl" が出力される。
どうしたらいいんだろう?ちなみに Groovy だけでも同じでした。
interface Test {
void print()
}
class Impl implements Test {
void print() {
println "impl"
}
}
class Impl2 implements Test {
void print() {
println "impl2"
}
}
// Test.metaClass.print = { println "class custom print" } // インターフェースのメタクラスだと、実装している全ての型のメソッドが変更される
def i = new Impl();
// i.metaClass.print = { println "instance custom print" } // インスタンスのメタクラスでは、動作が変わらない。
i.print() //
// Impl2.metaClass.print = { println "instance custom print" } // 型のメタクラスでは、動作が変わらない。
def i2 = new Impl2();
i2.print()