2011-10-21 8 views
4

ジェノリックスを使用して、特定のメソッドによってスローされるビジネス例外を定義したいとします(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で動作することを期待していました。

それができないことが判明した場合は、タイプシステムで何が起こっているのか、タイプ置換に関連して注釈が処理されているかについての洞察もありがとう。

答えて

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でのスローのルールが異なる点です。たぶん特別な場合があります。

+0

ありがとう、didierd、それは完璧な意味があります。 私は、特性の例での抽象型の代替使用が異なって動作することを期待していました。おそらくタイプリテラル置換のための語彙的魔法によってもコンパイラは実際に@throws(classOf [NameOfActualBizExceptionType] 。 私はそれを違う方法で行い、特性ではなくJavaインターフェイスを使用する必要があるということを受け入れることにします。それはあなたが目立つように正式なスローの位置で正式型パラメータを使うことができます。 – Dextaa

関連する問題