2012-03-13 8 views
3

ClassCastExceptionをキャッチする際に問題があります。 リトリーブ関数のパターンマッチングの最後のケースで発生しますが、例外は発生しません。スカラーのClassCastExceptionをキャッチできません

どうすればこの問題を解決できますか?

abstract class Property 

    object EmptyProperty extends Property 

    class PropertyCompanion[T] 

    object Type extends PropertyCompanion[Type] 
    case class Type extends Property 

    object Name extends PropertyCompanion[Name] 
    case class Name extends Property 

    abstract class Entity { 
    protected val properties: Map[PropertyCompanion[_], Property] 
    def retrieve[T](key: PropertyCompanion[T]) = 
     properties.get(key) match { 
     case Some(x) => x match { 
      case EmptyProperty => throw new Exception("empty property") 
      case _ => { 
      try { 
       x.asInstanceOf[T] 
      } catch { 
       case e => throw new Exception("fubar") 
      } 
      } 
     } 
     case None => throw new Exception("not found") 
     } 
    } 

    case class Book(protected val properties: Map[PropertyCompanion[_], Property]) extends Entity { 
    def getType = retrieve(Type) 
    def getName = retrieve(Name) 
    } 

    object Test extends App { 

    val book = Book(Map(Type -> Type(), Name -> Type())) 
    val name = book.getName 
    } 

答えて

5

あなたが;-)それを少しトリックする必要がありますので、実行時にTを知らないT.ザ・JVMにキャストすることはできませんので、あなたは、例外をキャッチすることはできません。メソッドにimplicit m: CLassManifest[T]を渡し、m.erasure.cast(x)を使用してください。あなたのようになりますことができます:

abstract class Property 

object EmptyProperty extends Property 

class PropertyCompanion[T] 

object Type extends PropertyCompanion[Type] 
case class Type extends Property 

object Name extends PropertyCompanion[Name] 
case class Name extends Property 

abstract class Entity { 
    protected val properties: Map[PropertyCompanion[_], Property] 
    def retrieve[T](key: PropertyCompanion[T])(implicit m: ClassManifest[T]) = 
    properties.get(key) match { 
     case Some(x) => x match { 
     case EmptyProperty => throw new Exception("empty property") 
     case _ => { 
      try { 
      m.erasure.cast(x).asInstanceOf[T] 
      } catch { 
      case e => throw new Exception("fubar") 
      } 
     } 
     } 
     case None => throw new Exception("not found") 
    } 
} 

case class Book(protected val properties: Map[PropertyCompanion[_], Property]) extends Entity { 
    def getType = retrieve(Type) 
    def getName = retrieve(Name) 
} 

object Test extends App { 

    val book = Book(Map(Type -> Type(), Name -> Type())) 
    val name = book.getName 
} 

編集:正しい戻り値の型に

+0

おかげで多くを得るためにTにキャストを追加しました。したがって、マニフェストを使用しないとこれには道はありませんか?パフォーマンスコストはかかりますか? – roelio

+0

また、 'result.asInstanceOf [T]'を返さなければならないのは、 'Any'型を返すからです。 – roelio

+0

' Class [T] 'のjavadocが表示されるので、私は奇妙ですこの表記法は 'T cast(Object obj)'です。私は別の方法があるとは思わない、それがスカラーがタイプ消去を欺く方法であるから。追加のオブジェクト割り当てよりもパフォーマンスコストはありません。 – drexin

関連する問題