Eclipse Galileo でJava コーディングを迅速に行う

新しい toString() 生成プログラムを使う

Eclipse Galileo での新しいコード生成機能、toString() の使い方を学びましょう。また、hashCode()equals()、セッター/ゲッターの生成機能の使い方も学び、Java™ クラスの基本部分を作成するのに必要な作業量を削減しましょう。

Nathan A. Good, Senior Information Engineer, Freelance Developer

Nathan GoodNathan A. Good はミネソタ州の Twin Cities エリアに住んでいます。彼はプロとしてソフトウェア開発やソフトウェア・アーキテクチャー、システム管理などを行っています。彼はソフトウェアを書いている時以外は、PC やサーバーを構築したり、新しい技術について資料を読んだり、そうした技術に取り組んだり、彼の友人達をオープソース・ソフトウェアに移行させようとしたりしています。彼は数多くの本や記事を執筆、あるいは共同で執筆しており、その中には『Professional Red Hat Enterprise Linux 3』や『Regular Expression Recipes: A Problem-Solution Approach』、『Foundations of PEAR: Rapid PHP Development』などがあります。



2009年 8月 18日

コード生成のヒントを紹介するこの記事では、Eclipse Galileo で導入された新しい機能を使います。ただし、この記事で説明する手法の一部、例えばゲッターとセッターの生成などは、古いバージョンの Eclipse (Ganymede など) でも使用することができます。

コード生成の概要

私が Eclipse で日常的に使用する機能のうち、最も頻繁に使う機能は、「Source (ソース)」メニューの中にあるコード生成のための項目です。それらの項目の効果的な使い方を理解するまで少し時間がかかりましたが、理解できてしまうと、Java クラスを極めて迅速に作成できるようになりました。

例えば新しいクラスを作成する場合、まったく時間をかけずにセッターとゲッター (アクセサー) を作成できるようになりました。コンストラクターを作成することはほとんどなくなり、代わりに、作成したクラスの中で使用するプライベート変数をすぐに宣言して型付けします (リスト 1)。

リスト 1. プライベート変数
public class Automobile {

    private String make;
    private String model;
    private String year;

}

それが終わったら、「Source (ソース)」 > 「Generate Getters and Setters (getter および setter の生成)」の順にクリックし、パブリック・アクセサーを使って公開する予定のプライベート変数 (先ほど型付けしたプライベート変数) を選択します。それらのプライベート変数の一部を、コンストラクターを使って初期化するためには、「Source (ソース)」 > 「Generate Constructor using Fields (フィールドを使用してコンストラクターを生成)」の順にクリックします。すると、すぐにコンストラクターが作成されます。そのクラスを使って何をするかによりますが、数回マウスをクリックするだけでほとんど完全なクラスが出来上がります (リスト 2)。何よりも良いことに、新しく作成されたコードは、Eclipse の「Preferences (設定)」に設定されたコード・フォーマットのルールに従ったものになります。

リスト 2. コンストラクターとアクセサーを自動的に作成する
public class Automobile {

    private String make;
    private String model;
    private String year;

    public String getMake() {
        return make;
    }

    public Automobile(String make, String model, String year) {
        super();
        this.make = make;
        this.model = model;
        this.year = year;
    }

    public void setMake(String make) {
        this.make = make;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

}

「Source (ソース)」メニューの中にある項目を使って生成できるコードの他にも、さまざまなコードを生成することができます。「Ctrl+スペース」のショートカットを使うと、一般的なコード・ブロックの多くを作成することができます。特定のブロックを生成するために必要な名前を知るためには、「Preferences (設定)」ウィンドウを調べます。例えば、「lazy」と入力してから「Ctrl+スペース」を押すと、遅延ローディングに使用できる Java コードが生成されます。


コード生成のための設定

新しいメソッドに対するコード生成の設定を変更するためには、「Preferences (設定)」ウィンドウで「Java」 > 「Code Style (コード・スタイル)」 > 「Code Templates (コード・テンプレート)」の順に選択します。

図 1. 「Preferences (設定)」ウィンドウで「Java」 > 「Code Style (コード・スタイル)」 > 「Code Templates (コード・テンプレート)」の順に選択する
「Preferences (設定)」ウィンドウで「Java」 > 「Code Style (コード・スタイル)」 > 「Code Templates (コード・テンプレート)」の順に選択する

ベスト・プラクティスをコード化する

私はいくつかのプロジェクトのテクニカル・リーダーとして、それらのプロジェクトで使用するためのベスト・プラクティスをいくつか特定しました。私はそれらのベスト・プラクティスを Java コード・テンプレートの中に入れ、チームのメンバーがインポートできるようにしてあります。

Preferences (設定)」ウィンドウで「Java」 > 「Editor (エディター)」 > 「Templates (テンプレート)」の順に選択すると、名前順にテンプレートのリストが表示されます (図 2)。Eclipse に同梱されているテンプレートを探します。独自のテンプレートを追加することもでき、さらにはテンプレートをインポートすることもできます。

図 2. 「Preferences (設定)」ウィンドウで「Java」 > 「Editor (エディター)」 > 「Templates (テンプレート)」の順に選択する
「Preferences (設定)」ウィンドウで「Java」 > 「Editor (エディター)」 > 「Templates (テンプレート)」の順に選択する

toString() 生成機能を使う

Eclipse Galileo での新しい機能として、toString() メソッドを生成することができます。toString() メソッドはデフォルトでクラスの表現を出力しますが、その表現の中には実際にユーザーが見たいと思っているプロパティーが表示されないかもしれません。リスト 3 の Main メソッドを考えてみてください。

リスト 3. toString() を使って Automobile を出力する
public class Main {
    public static void main(String[] args) {
        Automobile auto = new Automobile("Toyota", "Corolla", "1993");
        System.out.println(auto.toString());
    }
}

このアプリケーションの出力をリスト 4 に示します。

リスト 4. Main メソッドの出力Main method
Automobile@77df38fd

Galileo が登場する前は、toString() メソッドは手動でコーディングしなければなりませんでした。この例のように簡単なクラスの場合にはそれほど大変ではありませんが、もっと多くのフィールドがあるクラスの場合には、作成に長い時間がかかります。また、単純に値を連結する以上のことをしなければならない場合や、ヌルをチェックしたい場合、さらには StringBuilder を使ってパフォーマンスを高めたい場合があるかもしれません。しかし Galileo では、そうしたことをすべて、「Source (ソース)」 > 「Generate toString() (toString() の生成)」の順に選択することで実現できるのです (図 3)。

図 3. toString() 生成機能
toString() 生成機能

Finish (完了)」をクリックすると、新しい toString() メソッドはリスト 5 のようになります。

リスト 5. 自動的に生成された toString() メソッド
...
    @Override
    public String toString() {
        return "Automobile [" + (make != null ? "make=" + make + ", " : "")
                + (model != null ? "model=" + model + ", " : "")
                + (year != null ? "year=" + year : "") + "]";
    }
...

これで Main メソッドを実行すると、出力はリスト 6 のようになります。

リスト 6. 自動的に生成された toString() メソッドの出力
Automobile [make=Toyota, model=Corolla, year=1993]

ストリングのフォーマットを設定する

リスト 6 の出力はリスト 4 に示した元の出力よりもわかりやすい表現になっていますが、少しフォーマットを調整し、さらに読みやすくすると、もっと良くなるかもしれません (例えば「1993 Toyota Corolla (Automobile)」など)。カスタムのテンプレートを使用すると、toString() メソッド用に生成された出力を調整することができます。

toString() メソッドを削除し、「Source (ソース)」 > 「Generate toString() (toString() の生成)」の順に再度クリックします。そして今度は、

  1. String format (文字列の書式)」ドロップダウン・リストの隣にある「Edit (編集)」をクリックします。
  2. 表示された画面で「New (新規)」をクリックします。
    図 4. 新しいフォーマットを追加する
    新しいフォーマットを追加する
  3. Pattern (パターン)」の中に ${member.value} ${otherMembers} (${object.className}) のように入力し、そのパターンに名前を付け、「OK」をクリックします。

この新しいパターンが選択された状態で、「Generate toString() (toString() の生成)」画面で「OK」をクリックします。新しいコードはリスト 7 のようになります。

リスト 7. 更新された toString() メソッド
...
    @Override
    public String toString() {
        return (make != null ? make + " " : "")
                + (model != null ? model + " " : "")
                + (year != null ? year : "") + " (Automobile)";
    }
...

これで Main メソッドを実行すると、Automobile オブジェクトの toString() の出力はリスト 8 のようになります。

リスト 8. Automobile オブジェクトの toString() メソッドの出力
Toyota Corolla 1993 (Automobile)

配列を扱う

toString() 生成プログラムを使うと、配列も処理することができます。リスト 9 を考えてみてください。このリストは、新しい、options という名前のストリングの配列を示しています。

リスト 9. options という名前のストリングの配列
        Automobile auto = new Automobile("Toyota", "Corolla", "1993");
        String[] options = new String[] {
                "Automatic Transmission",
                "Power Brakes",
                "Power Windows"
        };
        // new generated method after adding private String[] options;
        auto.setOptions(options);
        System.out.println(auto.toString());
        // prints this:
        // Toyota Corolla [Ljava.lang.String;@defb836 1993 (Automobile)

通常、ネイティブの toString() メソッドは配列の表現を出力します。この表現はそのオブジェクトの元の表現とまったく同じですが、実際に配列の内容を表示することはありません。しかし、オプションの「List contents of arrays instead of using native toString (ネイティブの toString() を使用する代わりに配列のコンテンツをリスト)」を選択すると、それを変更することができます。このオプションを選択すると、toString() メソッドを再生成することができ、新しい出力はリスト 10 のようになります。

リスト 10. 再生成された toString() メソッドの出力
Toyota Corolla [Automatic Transmission, Power Brakes, Power Windows] 1993 (Automobile)

出力を制限する

配列の一部が非常に大きい場合には、出力される内容を制限することができます。そのためには「Limit number of items in arrays/collections/maps (配列/コレクション/マップ内の項目の数を次に制限)」を選択し、制限数を設定します (図 5)。こうすることによって、toString() メソッドによる大量の出力を制限することができます。

図 5. 配列の内容を出力し、ただし出力数を制限する
配列の内容を出力し、ただし出力数を制限する

リスト 11 は制限の設定を 2 にする場合の例を示しています。

リスト 11. 配列の内容の項目数を 2 に制限する
Toyota Corolla [Automatic Transmission, Power Brakes] 1993 (Automobile)

hashCode()equals() を使う

Eclipse Galileo の生成機能、hashCode()equals() は、フィールドの実際の値に基づいてオブジェクト同士を等しくするためのルールを作成したい場合に非常に便利です。これはデフォルトの equals() の動作とは異なります。デフォルトで同じ値を持つオブジェクト同士でさえ、等しいとは限らないからです。リスト 12 のコードを考えてみてください。

リスト 12. equals() メソッドのデフォルトの動作
public class Main {
    public static void main(String[] args) {
        Automobile auto = new Automobile("Toyota", "Corolla", "1993");
        String[] options = new String[] {
                "Automatic Transmission",
                "Power Brakes",
                "Power Windows"
        };
        auto.setOptions(options);
        
        Automobile auto2 = new Automobile("Toyota", "Corolla", "1993");
        String[] options2 = new String[] {
                "Automatic Transmission",
                "Power Brakes",
                "Power Windows"
        };
        auto2.setOptions(options2);
        
        System.out.println("Autos 1 and 2 are equal():  " + auto.equals(auto2));
        
    }
}

すべてのプロパティーは同じ値に設定されているにもかかわらず、このコードを実行すると「Auto 1 and 2 are equal(): false」という内容が出力されます。

この動作を変更するためには、「Source (ソース)」 > 「Generate hashCode() and equals() (hashCode() および equals() の生成)」の順にクリックし、すべてのフィールドを比較する新しいバージョンの equals() メソッドを生成します (リスト 13)。

リスト 13. 新しい equals() メソッドですべてのフィールドを比較する
    @Override
    public int hashCode() {
        // snipped...
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Automobile other = (Automobile) obj;
        if (make == null) {
            if (other.make != null)
                return false;
        } else if (!make.equals(other.make))
            return false;
        if (model == null) {
            if (other.model != null)
                return false;
        } else if (!model.equals(other.model))
            return false;
        if (!Arrays.equals(options, other.options))
            return false;
        if (year == null) {
            if (other.year != null)
                return false;
        } else if (!year.equals(other.year))
            return false;
        return true;
    }

これでこのコードを実行すると、オーバーライドされた equals() メソッドを使って 2 つのオブジェクトが比較され、この 2 つが等しいことがわかります。

Eclipse Galileo での、もう 1 つの新しい機能として、if 文のブロックを生成することができます。「Source (ソース)」 > 「Clean Up (クリーンアップ)」の順に選択することによって、1 行の if 文をブロックに変更する作業をまだ行っていない場合には、この新機能が便利です。通常のベスト・プラクティスとしては、1 行の if 文を避ける必要があると言われています。そのため大抵の人は、確実にそれを守ったコードを作成したいものです。


まとめ

Galileo には toString() メソッドを生成する新機能があり、これを利用することで大量の Java コードを生成する機能が既存の Eclipse の機能に追加されます。実際に使ってみることで、どのコードを型付けする必要があるのか、どのコードを生成できるのかを理解できるようになり、作業の量を減らせるようになります。

参考文献

学ぶために

  • Eclipse Galileo の接近調査」を読み、Galileo の機能について学んでください。
  • Eclipse の推奨読み物リスト」を調べてみてください。
  • developerWorks には他にも Eclipse に関する資料が豊富に用意されています。
  • developerWorks を Twitter でフォローしてください。
  • Eclipse が初めての人は、developerWorks の記事「Eclipse Platform 入門」を読んでください。Eclipse の起源やアーキテクチャー、またプラグインを使って Eclipse を拡張する方法などを学ぶことができます。
  • IBM developerWorks の Eclipse project resources を利用して Eclipse のスキルを磨いてください。
  • developerWorks podcasts ではソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。
  • developerWorks の Technical events and webcasts で最新情報を入手してください。
  • IBM とオープンソース技術、そして製品機能を調べ、学ぶために、無料の developerWorks On demand demos をご覧ください。
  • IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
  • developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。

製品や技術を入手するために

議論するために

  • Eclipse に関する質問を議論するための最初の場所として、Eclipse Platform newsgroups があります (このリンクをクリックすると、デフォルトの Usenet ニュース・リーダー・アプリケーションが起動し、eclipse.platform が開きます)。
  • Eclipse newsgroupsには、Eclipse を利用し、拡張することに関心を持つ人達のために、さまざまなリソースが用意されています。
  • developerWorks blogs から developerWorks のコミュニティーに加わってください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=428114
ArticleTitle=Eclipse Galileo でJava コーディングを迅速に行う
publish-date=08182009