【コラム】

Java API、使ってますか?

9 けっこう便利! 単位を扱うAPI -- JSR 275: Units Specification

 

9/60

JSR 275: Units Specificationについて

Java SE 7にJavaの新機能として追加される多くのJSRの中で、一風変わったJSRに「JSR 275: Units Specification」というものがある。JSR 275はJavaプログラムにおいて数量や単位を扱うための強力な機能を提供する拡張APIである。このAPIを使えば、同じint型やdouble型の値でも、その単位がメートルなのかマイルなのか、グラムなのかポンドなのかといったことを区別して扱うことができるようになる。また、メートルでの距離からマイルへの距離へ変換するなどといった単位変換のための機能も用意される。

JSR 275で提供される予定の主な機能を以下に挙げる。

  • 単位を扱うためのインタフェースや抽象クラス
  • それらのクラス/インタフェースによる以下の機能
    • 単位間の互換性
    • さまざまな単位における数量
    • 単位の演算
  • 一般的な単位に対する実装クラス
  • 文字列から単位へのパース
  • 単位から文字列へのフォーマッティング
  • 定義済み単位のデータベース

たとえば長さを表すdouble型のプロパティを持っているクラスを考えてみよう。通常のJavaプログラムでは、このdouble値がどの単位の長さを表すのか区別することができない。それどころか、誤って長さ以外の値を設定してしまったとしても、それを検出する有効な手段もない。JSR 275を使用することで、実世界で使用される単位を正確にモデリングすることができるようになる。

また、単位に関連する主要な値があらかじめ設定されている点も見逃せない。たとえば1マイルが何メートルなのかといった情報が保持されているため、単位変換も容易に行うことができる。

JSR 275の詳細な仕様はまだ公開されていないが、科学技術に関連したJavaライブラリの開発を目指すJScienceプロジェクトによって、すでにその参照実装が公開されている。まだ仕様が決まっていないため今後も大きな変更が加えられる可能性はあるが、今回は現時点での実装を用いてUnit Specificationの使用例を紹介しよう。

JSR 275の使用例

JSR 275の参照実装はJScienceの公式サイトからダウンロードすることができる。配布ファイルはJScienceで開発されている各種ライブラリがセットになった「jscience-3.3.Beta-bin.zip」で、これに含まれている「jscience.jar」をにクラスパスに含めて使用する。

JSR 275は大きく3つのパートに分かれており、それぞれ次に挙げるパッケージでまとめられている。

  • java.measure.units: 単位を表すクラス/インタフェースが提供される
  • javax.measure.quantities: 測定可能な数量を表すクラス/インタフェースが提供される
  • javax.measure.converters: 単位の変換を行うためのクラスが提供される

単位の基本となるのはjava.measure.units.Unitクラスで、このクラスのインスタンスとしてさまざまな単位がjava.measure.units.SIおよびjava.measure.units.NonSIクラスに定義されている。

Unitのクラス定義は「Unit<Q extends Quantity>」となっている。このjavax.measure.quantities.Quantityというのは数量を表すための基底インタフェースで、このインタフェースを継承して長さや重さなどを表すさまざまなインタフェースが多数用意されている。Quantityの定義は「Quantity<Q extends Quantity>」となっているため、自身のサブインタフェースでパラメータ化されることになる。

たとえば、このAPIを利用して単位の変換を行うにはリスト1のようにする。まずSIクラスにはメートル単位を表すSI.METERという定数が用意されており、これをSI.METER()メソッドでキロ単位に変換している。長さの単位を表す型はUnit<Length>となる。続いてgetConverterTo()メソッドでマイル単位であるNonSI.MILEへのコンバータを取得し、convert()メソッドで変換を行っている。

リスト1 UnitSample.java - JSR 275を使用した単位の変換

package apisample;

import javax.measure.quantities.Mass;
import javax.measure.quantities.Scalar;
import javax.measure.units.NonSI;
import javax.measure.units.SI;

public class PersonSample {
    public static void main(String[] args) {
        Person person = new Person();

        // 体重をキログラムでセット
        Scalar weight = new Scalar(60, SI.KILOGRAM);
        person.setWeight(weight);
        Scalar returnWeight = (Scalar)person.getWeight();
        System.out.println(weight.doubleValue(SI.KILOGRAM) + "キログラム");
        System.out.println(weight.doubleValue(NonSI.POUND) + "ポンド");

        // 体重をポンドでセット
        weight = new Scalar(140, NonSI.POUND);
        person.setWeight(weight);
        returnWeight = (Scalar)person.getWeight();
        System.out.println(weight.doubleValue(SI.KILOGRAM) + "キログラム");
        System.out.println(weight.doubleValue(NonSI.POUND) + "ポンド");

        // System.out.println(weight.doubleValue(SI.METER) + "メートル");  // コンパイルエラー
    }
}

このプログラムの実行結果はプロンプト2のようになる。

プロンプト2

> java [PATH_TO_JSCIENCE] UnitSample
100キロ = 62.1371192237334マイル

JSR 275をリスト2のように使うと、オブジェクトのプロパティに入れる値の単位を明確にすることができる。Personクラスの場合、weightプロパティは体重を表すようにしたいので、javax.measure.quantities.Massを利用してQuantity<Mass>型にしてある。

リスト2 Person.java

package apisample;

import javax.measure.quantities.Mass;
import javax.measure.quantities.Quantity;

public class Person {
    private Quantity weight;

    public void setWeight(Quantity weight) {
        this.weight = weight;
    }
    public Quantity getWeight() {
        return this.weight;
    }
}

Personクラスはリスト3のようにして使う。Quantityを実装したクラスは、スカラー値を表すjavax.measure.quantities.Scalarクラスのみ用意されている。今回は、数値と単位(SI.KILOGRAM)を指定して体重のスカラー値(Scalar<Mass>)を作成して、それをPersonオブジェクトにセットしている。

Quantityインタフェースに宣言されているdoubleValue()およびlongValue()メソッドは、引数に任意のUnitを指定すれば、数値をその単位に自動的に変換して返してくれる。したがって今回はweight.doubleValue(SI.KILOGRAM)のようにすればキログラム単位の値が得られ、weight.doubleValue(NonSI.POUND)とすればポンド単位の値が得られる。変換に対応していないUnitが指定された場合は当然コンパイルできない。

リスト3 PersonSample.java

package apisample;

import javax.measure.quantities.Mass;
import javax.measure.quantities.Scalar;
import javax.measure.units.NonSI;
import javax.measure.units.SI;

public class PersonSample {
    public static void main(String[] args) {
        Person person = new Person();

        // 体重をキログラムでセット
        Scalar weight = new Scalar(60, SI.KILOGRAM);
        person.setWeight(weight);
        Scalar returnWeight = (Scalar)person.getWeight();
        System.out.println(weight.doubleValue(SI.KILOGRAM) + "キログラム");
        System.out.println(weight.doubleValue(NonSI.POUND) + "ポンド");

        // 体重をポンドでセット
        weight = new Scalar(140, NonSI.POUND);
        person.setWeight(weight);
        returnWeight = (Scalar)person.getWeight();
        System.out.println(weight.doubleValue(SI.KILOGRAM) + "キログラム");
        System.out.println(weight.doubleValue(NonSI.POUND) + "ポンド");

        // System.out.println(weight.doubleValue(SI.METER) + "メートル");  // コンパイルエラー
    }
}

プロンプト2 PersonSampleの実行例

> java [PATH_TO_JSCIENCE] PersonSample
60.0キログラム
132.27735731092656ポンド
63.5029318キログラム
140.0ポンド

JSR 275には今回紹介した以外にも、各Unitの表記を取得する機能や、単位の次元を取得する機能、次元の互換性を判定する機能などを備えている。また、各Unitどうしの演算を行うこともできる。JSR 275は決して目を見張るような派手な機能を提供してくれるAPIではないが、これまで曖昧だった数値の扱いをより明確にすることで、プログラムの可読性や安全性を向上させてくれることだろう。

提供:毎日就職ナビ

会員登録はこちら

学生のための就職情報サイト「毎日就職ナビ」。6,000社以上の新卒採用情報が常時掲載され、社内の雰囲気が伝わる情報画面、さまざまな項目での会社検索、エントリーや説明会検索など、機能も充実。無料適職診断、就活Q & A、エントリーシート添削講座など、就職活動に役立つ記事も満載です。研究者、エンジニアを目指す学生の方々も是非エントリーしてください。お待ちしています!

毎日コミュニケーションズはプライバシーマークを取得しています。

9/60

インデックス

連載目次
第60回 どうなる? 今後のJavaプラットフォーム(Java SE編)
第59回 どうなる? 今後のJavaプラットフォーム(Java EE編)
第58回 Java SE 7の要注目機能"クロージャ"はどうなるのか その6
第57回 Java SE 7の要注目機能"クロージャ"はどうなるのか その5
第56回 Java SE 7の要注目機能"クロージャ"はどうなるのか その4
第55回 Java SE 7の要注目機能"クロージャ"はどうなるのか その3
第54回 Java SE 7の要注目機能"クロージャ"はどうなるのか その2
第53回 Java SE 7の要注目機能"クロージャ"はどうなるのか
第52回 Early Draftが公開されたJSF 2.0
第51回 EJBから独立したJava Persistence 2.0
第50回 モバイルJavaの新しい潮流となるか - MSA 2.0のドラフト公開
第49回 やっぱり基本はServlet - Servlet 3.0のEarly Draftを読む
第48回 JOGLで3Dプログラミング その4
第47回 JOGLで3Dプログラミング その3
第46回 JOGLで3Dプログラミング その2
第45回 JOGLで3Dプログラミング
第44回 JARファイルを効率的にネットワーク転送するためのPack200形式
第43回 Early Draftで把握するEJB 3.1の新機能
第42回 次世代の携帯端末向けJava仕様"MIDP 3.0"はどうなるか その2
第41回 次世代の携帯端末向けJava仕様"MIDP 3.0"はどうなるか その1
第40回 リソースアダプタによる接続の仕組み
第39回 JCAを利用したシステム間接続
第38回 Java EEと外部システムの接続性を支えるJCAがバージョンアップ
第37回 Javaのモジュラリティ強化を担う"スーパーパッケージ"とは
第36回 JSR 308対応のコンパイラを試す
第35回 公開されたJSR 308のEarly Draftを検証する
第34回 スクリプト言語とJavaを結びつけるJSR 223
第33回 Java EE環境に統一されたコンポーネントモデルを提供するJSR 299 その2
第32回 Java EE環境に統一されたコンポーネントモデルを提供するJSR 299 その1
第31回 Javaの文法がそのまま使えるスクリプト言語"BeanShell"
第30回 Javaアプリケーションにオブジェクトのキャッシュ機構を提供するJCache API
第29回 Javaアプリケーションからのリソース管理を可能にするJSR 284
第28回 XMLデータソースへの問い合わせはJSR 225で
第27回 Portlet Specification 2.0をもっと手軽に利用する
第26回 次期Javaポートレット仕様となるJSR 286
第25回 JSFとポートレットをつなげるJSR 301
第24回 Webサービス向けのポートレット仕様「WSRP」
第23回 高い相互運用性を実現するポートレットAPI - JSR 168
第22回 Java EE環境でタスクのスケジューリングを可能にするJSR 236
第21回 Java EE環境でのスレッドプログラミングを可能にするJSR 237
第20回 音声認識/合成のためのAPI - Java Speech APIとJSR 113
第19回 JSR 291でJavaプラットフォームにダイナミックコンポーネントモデルを導入
第18回 JAX-RSで簡単RESTful - JSR 311
第17回 待望のServlet 3.0がJSRに登場 - JSR 315
第16回 アノテーションを使ってバグ退治 - JSR 305
第15回 アノテーションをさらに広い範囲で利用可能にするJSR 308
第14回 Webアプリケーション開発の要となるか - JSF 2.0がJSRに登場
第13回 Webサービス経由でのJMX Agentへの接続を可能にするJSR 262
第12回 Javaアプリケーションのモジュール化をサポートするJava Module System
第11回 "NIO.2"がやってきた - JSR 203: More New I/O APIs for the Java Platform
第10回 JSR 295: Beans Bindingの参照実装を試す
第9回 けっこう便利! 単位を扱うAPI -- JSR 275: Units Specification
第8回 アノテーションでバリデーション - JSR 303: Bean Validator
第7回 Swing開発の救世主となるか - Swing Application Framework
第6回 JavaBeansのプロパティを同期させるバインディングAPI
第5回 誰よりも早く"Java SE 7"を睨む
第4回 日時情報の取り扱いを改善する JSR 310: Date and Time API
第3回 古いAPIも進化している!? - JSR 919: JavaMail 1.4
第2回 JSR 1 リアルタイムJava仕様
第1回 JCPによって進められるJava関連技術の標準化

もっと見る

提供:マイナビ

会員登録はこちら

大学・大学院・短大・専門学生向けの就職情報サイト「マイナビ2010」「マイナビ2009」に今すぐ登録しよう!  大手企業からベンチャー企業までの約13,000社の企業情報を公開、エントリーが可能です。2010年卒予定の方は「マイナビ2010」に、2009年卒予定の方は「マイナビ2009」に登録してください。

毎日コミュニケーションズはプライバシーマークを取得しています。



転職ノウハウ

あなたが本領発揮できる仕事を診断
あなたの仕事適性診断

シゴト性格・弱点が20の質問でサクッと分かる!

「仕事辞めたい……」その理由は?
「仕事辞めたい……」その理由は?

71%の人が仕事を辞めたいと思った経験あり。その理由と対処法は?

3年後の年収どうなる? 年収予報
3年後の年収どうなる? 年収予報

今の年収は適正? 3年後は? あなたの年収をデータに基づき予報します。

激務な職場を辞めたいが、美女が邪魔して辞められない
激務な職場を辞めたいが、美女が邪魔して辞められない

美人上司と可愛い過ぎる後輩に挟まれるエンジニアの悩み

人気記事

一覧

イチオシ記事

新着記事

アウディ「TT クーペ」にエントリーグレードを追加 - 限定モデル2台も発売
[05:27 8/28] ホビー
ボルボ「XC90 エクセレンス」発表 - 後席の居住性を重視した4人乗り高級SUV
[05:16 8/28] ホビー
ボルボ「XC60 クラシック」をラインアップに追加 - 装備を充実させたモデル
[04:58 8/28] ホビー
メルセデス・ベンツ「C 300 クーペ スポーツ」を発売 - 専用エンジンを搭載
[04:44 8/28] ホビー
「メルセデスAMG C 43 4MATIC」9速AT搭載などの改良を実施 - クーペ追加も
[04:39 8/28] ホビー

求人情報