说你给出的一个实例List[Class[_ <: Base]]
,并说许多类扩展Base
:
class A extends Base
class B extends Base
class C extends A
Run Code Online (Sandbox Code Playgroud)
等等......
现在,给定的列表可能只包含一些类.例如:val classes = classOf[A] :: Nil
嗯,如果我val
的类是在列表中找到的类型,或者如果它是列表中类的子类,我如何测试实例化?即如何实施:
def testClass(class : List[Class[_ <: Base]], instance : Base) : Boolean
何时:
val classes = classOf[A] :: Nil
testClass(classes, new A) // should return true
testClass(classes, new B) // should return false
testClass(classes, new C) // should return true
Run Code Online (Sandbox Code Playgroud)
用例:
我正在尝试编写一个通用的重试模式,即获取一些非常容易出错的代码,并且我想重试执行一些最大次数的尝试,当每次失败时,它应该执行一些"等待" " 方法.
例如
retryRequest({
//Some code that throws exceptions
}, classOf[SomeException] :: classOf[SomeOtherException] :: Nil,
100, {Thread.sleep(5000)})
Run Code Online (Sandbox Code Playgroud)
这很好用,但它不会测试给定异常的子类:
def retryRequest(req : => Unit, validExceptions : List[Class[_ <: java.lang.Throwable]], tries : Int, waitMethod : => Unit) {
var keepTrying = false
var tryCount = 0
do{
try{
logger.debug("retryRequest, try #" + tryCount)
keepTrying = false
req
}catch{
case ex if(tryCount >= tries && validExceptions.contains(ex.getClass)) => {
throw new MaxTriesReachedException("tried for " + tryCount + "times, but no luck. " +
"you may want to try ommitting generic exceptions types from the given list.")
}
case ex if (validExceptions.contains(ex.getClass)) => {
logger.debug("intercepted " + ex.toString)
tryCount += 1
keepTrying = true
waitMethod
}
}
}while(keepTrying)
}
Run Code Online (Sandbox Code Playgroud)
我真的想要替换:
validExceptions.contains(ex.getClass)
Run Code Online (Sandbox Code Playgroud)
有类似的东西:
validExceptions.exists(exClass => ex.isInstanceOf[exClass]) //won't compile
Run Code Online (Sandbox Code Playgroud)
可能吗?怎么样?
一种更简单的方法是使用util.control.Exception
:
def retryRequest(req: => Unit,
validExceptions: List[Class[_ <: Throwable]],
tries: Int,
waitMethod: => Unit): Unit =
(Exception.catching(validExceptions:_*) withApply { e =>
waitMethod
if (tries > 1) retryRequest(req, validExceptions, tries - 1, waitMethod)
}) { req }
retryRequest( { println("a"); throw new Exception },
List(classOf[Exception]),
3,
Thread.sleep(100))
Run Code Online (Sandbox Code Playgroud)
简而言之:withApply
当catching
抛出一个传递给异常的异常时,接受一个处理该情况的闭包.在我们的例子中,我们只是递归地称呼自己(假设重试次数很少,我认为这不是问题).
我认为这应该有效:
validExceptions.exists(exClass => exClass.isAssignableFrom(ex.getClass))
Run Code Online (Sandbox Code Playgroud)
http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom%28java.lang.Class%29