加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

斯卡拉:谁能解释一下?

发布时间:2020-12-16 09:39:36 所属栏目:安全 来源:网络整理
导读:请考虑以下Scala代码: case class Data[T](value: Option[T]) { def get: T = try { doGet } catch { case e: Exception = throw new IllegalArgumentException } def doGet: T = value match { case Some(v) = v case None = ().asInstanceOf[T] }}Data[Un
请考虑以下Scala代码:

case class Data[T](value: Option[T]) {
  def get: T = try {
    doGet
  } catch {
    case e: Exception => throw new IllegalArgumentException
  }

  def doGet: T = value match {
    case Some(v) => v
    case None => ().asInstanceOf[T]
  }
}

Data[Unit](None).get
Data[Integer](None).get // which exception is thrown here?

[spoiler]这是一个ClassCastException;谁可以解释为什么它不被抓住并被IllegalArgumentException替代?

PS:为了抢占任何问题,我为什么要这样做:这是一些使用json4s将某些字符串解析成Option [T]的代码的简化版本。如果解析失败,则返回None,如果T为Unit,则为OK,如果T为其他类型则为OK。

解决方法

说明

异常不在这里抛出:

().asInstanceOf[T]

因为这是一个未经检查的转换 – JVM无法验证是否可以将()转换为T,因为它没有关于T的类型擦除信息。

相反,这里抛出异常

Data[Integer](None).get

因为get的结果被转换为整数,这是JVM可以验证的。所以,ClassCastException实际上是在get之外抛出的。

BTW,javac总是警告关于未经检查的转换,我不知道为什么scalac不。

解决方法

在某种程度上,可以使用ClassTag和基于反射的投射来解决类型擦除:

import scala.reflect.{ClassTag,classTag}

case class Data[T: ClassTag](value: Option[T]) {
  def get: T = try {
    doGet
  } catch {
    case e: Exception => throw new IllegalArgumentException
  }

  def doGet: T = value match {
    case Some(v) => v
    case None => classTag[T].runtimeClass.asInstanceOf[Class[T]].cast(())
  }
}

Hackaround

对于这种用例,您可以直接检查ClassTag:

scala> case class Data[T](value: Option[T])(implicit t: ClassTag[T]) {
     | def get: T = value getOrElse (t match {
     |   case ClassTag.Unit => ().asInstanceOf[T]
     |   case _ => throw new IllegalArgumentException
     | })
     | }
defined class Data

scala> Data[Unit](None)
res6: Data[Unit] = Data(None)

scala> .get

scala> Data[Int](None).get
java.lang.IllegalArgumentException

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读