2011-08-05 24 views
0

檢查我有下面的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返回一個Class [_],而不是類[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

這就近了。但考慮以下情況:A類; B類擴展A {def foo(){}};您提出的代碼允許我調用Test.invokeMethods [A](new A,classOf [B]),這會導致運行時異常。我的問題是這是否可以在編譯時檢查。 – user881423