Определение сигнатуры исключения Scala с использованием обобщений - PullRequest
4 голосов
/ 21 октября 2011

Я бы хотел использовать универсальные шаблоны, чтобы определить, какое бизнес-исключение выдается данным методом (метод 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.

Если окажется, что это невозможно, я также был бы признателен за понимание того, что происходит с системой типов, или порядка, в котором обрабатываются аннотации относительно замены типов.

1 Ответ

3 голосов
/ 21 октября 2011

На самом деле, это было бы то же самое в Java для аннотации.Если вы создаете аннотацию

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

, вы можете сделать throwing{exceptionType = RuntimeException.class}, но не throwing{exceptionType = E.class}.Вы не можете сделать E.class в Java или classOf[E] в Scala.

Вы не можете поместить параметр типа в аннотацию.Проблема в том, что в scala @throws является аннотацией и следует правилам для аннотаций, но правила для бросков на JVM отличаются.Возможно, будет оправдан особый случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...