使用泛型的Scala异常签名定义

时间:2011-10-21 11:09:55

标签: generics scala

我想使用泛型来定义给定方法抛出哪个业务异常(scala方法将从Java调用,因此它必须在签名中)。

以下是我在Java中的表现:

public interface BaseInterface<T, E extends Throwable> {
    public T process(Class<E> wrapperExc) throws E;    
}

public class ExcOne extends Exception {}

public class SubclassOne implements BaseInterface<String, ExcOne> {
    @Override
    public String process(Class<ExcOne> wrapperExc) throws ExcOne {
        return null;
    }
}

以下是我在Scala中尝试的内容:

class UsingGenerics[IN, OUT, E <: Throwable] {

    //@throws(classOf[E]) - error: class type required but E found
    def process(request: IN, wrapperExc: Class[E]): OUT = {
        null.asInstanceOf[OUT]
    }    

}

和..

trait BaseTrait {

    type Request
    type Response
    type BusinessException <: Throwable

    //error: class type required but BaseTrait.this.BusinessException found 
    //@throws(classOf[BusinessException])
    def process(request: Request): Response    

}

class TraitImplementor extends BaseTrait {

    type Request = Input
    type Response = Output
    type BusinessException = BizExc

    def process(r: Request): Response = {
        if (1 != 2) throw new BusinessException("Bang")
        new Response
    }

}

class Input
class Output
class BizExc(msg: String) extends Exception(msg)

Scala代码中的两个注释行都无法编译。

如果有人能解释如何使这项工作,我将不胜感激。

对我来说,'抛出新的BusinessException(“Bang”)'表示类型别名'BusinessException'是一个编译时间文字,因此我希望它能与classOf一起使用。

如果事实证明它无法完成,我也很欣赏任何关于类型系统发生了什么或者相对于类型替换处理注释的顺序的见解。

1 个答案:

答案 0 :(得分:3)

实际上,在java中注释也是一样的。 如果您创建注释

public @interface Throwing { Class<? extends Throwable> exceptionType(); }

你可以throwing{exceptionType = RuntimeException.class}而不是throwing{exceptionType = E.class}。您不能在java中E.class或在scala中执行classOf[E]

您不能在注释中放置类型参数。问题在于scala @throws是一个注释,并遵循注释规则,但JVM上的抛出规则是不同的。也许有必要保证一个特例。