JSR-275:单位和计量

  • Geoffrey Wiseman
  • 郭晓刚

2007 年 10 月 17 日

话题:Java语言 & 开发架构

JSR-275:单位规范》的目标是为 Java 软件开发增加计量单位的支持,以期能减少某些类型的错误。该规范的领导之一 Jean-Marie Dautelle 为我们介绍这个 API:

不恰当的物理测量模型会导致严重的程序设计错误。特别是将计量建模成单纯的数字而不管其代表的单位,会产生出脆弱的代码。其他开发者或者代码的其他部分都可能会错误地把数字看成代表其他计量单位。例如,一个人的重量数字的单位到底是磅、千克还是英石,并不容易看出来。这个问题很难通过测试来解决,而且已经给社会造成了数以百万计的金钱损失。(NASA 损失了价值 $1.25 亿的火星探测器,就因为 Lockheed Martin 的工程师使用英制单位,而 NASA 的工程师使用更适合关键太空任务的公制单位。)

JSR-275 引入了一个新的 javax.measure 包,其中包含一个 Measurable 接口和一个 Measure 类。

Measurable 表示一个属性可被量度(例如海拔、高度等),且给定一个相容的单位,可取得该属性的值:

Measurable<length> height = person.getHeight();


long inches = height.longValue(NonSI.INCH);

Measurable 用泛型来保证类型安全;如果传递一个 Measurable<mass> 对象到一个接受 Measurable<length> 参数的方法,就会产生编译错误:

Measurable<mass> weight = person.getWeight();


person.setHeight( weight ); // error!

Measure 代表一个具体的计量,是一个数字值和一个具体单位的结合。一个可计量的值(如 geoffreyWiseman.getHeight())可有不同的表示(如 Measure.valueOf(73,NonSI.INCH)、Measure.valueOf(1.8542,SI.METRE)) 。

API 中还包括了量的表示(quantities)(如质量、高度、功率、压力),用来参数化计量的泛型表示;单位(INCH、METER 等)被置于单位系统中。SI 表示公制,包括单位以及前缀(METER、KILO(METER) 等);NonSI 包含了不属于公制的常用单位(日、英尺、节等)。

可以用 UnitConverter 来转换同一量纲的单位。它可以解析和格式化带单位的数值,甚至包括含有不同单位的复合表示,如英尺和英寸、时分秒。这个 API 是可扩展的,支持创建新的单位、单位系统以及量的表示。

有些讨论谈及 JSR-275 来支持 JSR-310(日期 / 时间 API),这个主题还有待深入。Stephen Colebourne 在《JSR-275: Suitable for Java 7?》中指出日期 / 时间单位在转换中不具备科学单位的一致性:

呃,我们怎样精确地在月和日之间转换?这种转换到底是什么意思?我姑且猜测,它是将 1 年定义为 365 日 5 小时 49 分 12 秒,然后定义 1 月是其 1/12。然后根据这个数据进行月与日之间的转换。

更详细的信息请查阅规范或者参考实现

查看英文原文:JSR-275: Units and Measures Introduced
Java语言 & 开发架构