Не удается поймать ClassCastException в Scala - PullRequest
4 голосов
/ 14 марта 2012

У меня возникла проблема с перехватом 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
  }

1 Ответ

5 голосов
/ 14 марта 2012

Вы не можете поймать Исключение, потому что вы не можете привести к T. JVM не знает T во время выполнения, поэтому вам придется немного его обмануть ;-).Передайте 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
}

edit: добавили приведение к T, чтобы получить правильный тип возврата

...