2011-08-05 17 views
0

にチェックを入力し、私は以下のScalaのコード反射とScalaの

def invokeMethods(instance: AnyRef, clazz: Class[_]) { 
    assert(clazz.isInstance(instance) // <- is there a way to check this statically? 

    for {method <- clazz.getDeclaredMethods 
     if shouldInvoke(method) // if the method has appropriate signature 
     } method.invoke(instance) 
} 

// overload for common case 
def invokeMethods(instance: AnyRef) { 
    invokeMethods(instance, instance.getClass) 
} 

を持っているこれは正常に動作しますが、実行時のアサーションは、コンパイル時の型チェックと置き換えることができるのだろうか。私の素朴な試みは

def invokeMethods[T <:AnyRef](instance: T, clazz: Class[T]) { 
    for {method <- clazz.getDeclaredMethods 
     if shouldInvoke(method) 
     } method.invoke(instance) 
} 

に最初の方法を変更することですが、instance.getClassではなくクラスのクラス[_] [T]を返すので、私は第二の方法でコンパイル・エラーが発生します。これを回避する方法はありますか?

答えて

1

次のコンパイルは、お探しのものですか?

object Test { 
    def shouldInvoke(m: java.lang.reflect.Method) = true 
    def invokeMethods[T <:AnyRef](instance: T, clazz: Class[_ <: T]) { 
    for {method <- clazz.getDeclaredMethods 
     if shouldInvoke(method) 
    } method.invoke(instance) 
    } 

    def invokeMethods[T <: AnyRef](instance: T) { 
    invokeMethods(instance, instance.getClass) 
    } 
} 
+0

これは近いです。しかし、次のシナリオを考えてみましょう。クラスBはA {def foo(){}}を拡張します。あなたが提案したコードでは、実行時例外を引き起こすTest.invokeMethods [A](new A、classOf [B])を呼び出すことができます。私の質問は、これがコンパイル時にチェックできるかどうかです。 – user881423