Java中用户定义的值类是什么样的? [英] What do user-defined value classes look like from Java?

查看:87
本文介绍了Java中用户定义的值类是什么样的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过与Haskell的newtype进行比较,我认为我了解了Scala 2.10的新值类别"功能:

I think I understand the new "value class" feature of Scala 2.10, by comparison with Haskell's newtype:

trait BoundedValue[+This] extends Any { this: This =>

  def upperBound: This

  def lowerBound: This

}

class Probability @throws(classOf[IllegalArgumentException]) (v: Double) extends AnyVal with BoundedValue[Probability] {

  val value: Double = if ((v >= 0.0) && (v <= 1.0)) v else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]")

  override val upperBound: Probability = new Probability(0.0)

  override val lowerBound: Probability = new Probability(1.0)

  // Implement probability arithmetic here;
  // will be represented by Double at runtime.

}

我的问题是,值类如何在使用Scala包声明的Java代码中出现?值类是从Java方面显示为参考类,还是被完全擦除(因此以其包装的类型出现)?换句话说,在源代码级别涉及Java时,值类的类型安全性如何?

The question I have is, how does a value class appear to Java code that uses the Scala package in which it is declared? Does the value class appear as a reference class from the Java side, or is it erased completely (and thus appears as the type it wraps)? In other words, how type-safe are value classes when Java is involved on the source level?

编辑

根据SIP-15文档(在Daniel的答案中链接),上述代码无法编译,因为不允许值类具有任何初始化逻辑,因为v必须显式为val或Probability的伴随对象上必须具有unbox方法和相应的box方法,并且因为值类必须恰好具有一个字段.正确的代码是:

The code above won't compile, according to the SIP-15 document (linked in Daniel's answer), because value classes aren't allowed to have any initialization logic, because either v must be explicitly a val or Probability must have an unbox method and a corresponding box method on it's companion object, and because value classes must have exactly one field. The correct code is:

trait BoundedValue[This <: BoundedValue[This]] extends Any { this: This =>

  def upperBound: This

  def lowerBound: This

}

class Probability private[Probability] (value: Double) extends AnyVal with BoundedValue[Probability] {

  @inline override def upperBound: Probability = new Probability(0.0)

  @inline override def lowerBound: Probability = new Probability(1.0)

  @inline def unbox: Double = value

  // Implement probability arithmetic here;
  // will be represented by Double at runtime (mostly).

}

object Probability {

  @throws(classOf[IllegalArgumentException])
  def box(v: Double): Probability = if ((v >= 0.0) && (v <= 1.0)) new Probability(v) else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]")

}

问题本身仍然有效.

推荐答案

值类作为普通类进行编译,并且很可能作为引用出现.

Value classes compile as normal classes, and may well appear as references.

其中的妙处在于,当值类没有逃脱作用域时,它的所有痕迹都会从代码中删除,从而有效地内联所有代码.而且,当然,还提供了额外的类型安全性.

The magic in them is that, when the value class doesn't escape the scope, all traces of it are erased from code, effectively inlining all the code. And, of course, giving additional type safety.

另请参见 SIP-15 ,其中介绍了机制

See also SIP-15, which explains the mechanics.

这篇关于Java中用户定义的值类是什么样的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆