【问题标题】:Scala exception signature definition using genericsScala 异常签名定义使用泛型
【发布时间】:2011-10-21 11:09:55
【问题描述】:

我想使用泛型来定义给定方法抛出的业务异常(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 代码中的两条注释行都无法编译。

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

对我来说,'throw new BusinessException("Bang")' 表示类型别名 'BusinessException' 是编译时文字,因此我希望它可以与 classOf 一起使用。

如果事实证明无法做到这一点,我也希望能深入了解类型系统发生的情况或注释相对于类型替换的处理顺序。

【问题讨论】:

    标签: generics scala


    【解决方案1】:

    其实在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上抛出的规则是不同的。可能需要特殊情况。

    【讨论】:

    • 感谢 didierd,这很有意义。我曾希望 trait 示例中抽象类型的替代使用可能会有所不同——甚至可能是类型文字替换的一些词法魔法可能导致编译器实际上看到 @throws(classOf[NameOfActualBizExceptionType]) 但似乎没有。我只是接受我需要以不同的方式做它并使用 Java 接口而不是特征 - 这样我就可以在 throws 位置使用正式的类型参数,正如你所区分的那样,这是合法的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2014-12-11
    • 2012-02-06
    • 2014-08-13
    • 1970-01-01
    相关资源
    最近更新 更多