我在反射(reflection)地调用一个方法,该方法的参数可能是value class的实例,也可能不是。因为值类的目的是避免对基础值进行装箱,所以如果参数类型为值类,则所讨论的方法实际上将期望未装箱的值。为了处理这种情况,我试图从值类中解开基础值。我首先需要确定参数是否属于值类,在这里,我遇到了第一个绊脚石:

def isObjectOfValueClass(arg: Any) =
  classOf[AnyVal].isAssignableFrom(arg.getClass)

这无法按预期工作,因为该方法返回true:
case class NonValueClass(underlying: Int)
isObjectOfValueClass如何实现?还是有一种更简单的方法来反射性地调用可能将值类的对象作为参数的方法?

最佳答案

首先,请注意,您的isObjectOfValueClass将获得盒装版本的值类实例。

其次,它不能像您想要的那样工作。这是因为classOf[AnyVal] == classOf[AnyRef] == <java.lang.Object>

没有运行时方法可以区分装箱的值类和引用类(Any没有.instanceOf[T]AnyVal不能用于模式匹配或用作.instanceOf[T]的参数,最重要的是,编译后的值类不能扩展或实现AnyVal )。

如果您希望它决定编译时间,请尝试:

case class IsAnyVal[-T](val value: Boolean) extends AnyVal
implicit def _noClueHowToNameThisImplicit_1 = IsAnyVal[AnyVal](true)
implicit def _noClueHowToNameThisImplicit_2 = IsAnyVal[AnyRef](false)
def isAnyVal[T](arg: T)(implicit ev: IsAnyVal[T]) = ev.value

scala> isAnyVal(1)
res4: Boolean = true

scala> isAnyVal("")
res5: Boolean = false

我不确定如何在没有更多意外装箱的情况下提取检测到的装箱值类实例的唯一字段。此外,Hotspot非常擅长优化小型短期对象。

关于Scala:识别值类别的对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19656353/

10-09 02:52