プログラマーの常識をJavaで身につける
連載一覧へ
プログラマーの常識をJavaで身につける (11)

いまさら聞けないJavaによるオブジェクト指向の常識


株式会社 NTTデータ ビジネスブレインズ
伊賀敏樹
山本耕司
2008/5/8


Java APIの「裏技」java.lang.reflectパッケージとは?

 Java言語には、java.lang.reflectパッケージを通じて「裏技」のようなAPIが提供されています。このjava.lang.reflectパッケージを利用すると、公開されていないクラスのフィールドやメソッドを「のぞき見」できてしまいます。

java.lang.reflectパッケージで、クラスを「のぞき見」

 ここでは、ラーメン・クラスをのぞき見してみます。

SnoopRamen.java
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
* ラーメン・オブジェクトをのぞき見するクラス
*/

public class SnoopRamen {
    public static void main(final String[] args)
    throws IllegalArgumentException, IllegalAccessException {
        final IRamen ramen = new Ramen();

        // ラーメン・インスタンスから
        // java.lang.Classインスタンスを取得
        final Class classRamen = ramen.getClass();

        System.out.println("フィールド一覧");
        // フィールド一覧を取得
        final Field[] fields = classRamen.getDeclaredFields();
        for (int index = 0; index < fields.length; index++) {
            final Field field = fields[index];
            System.out.println(" " + field.toString());
        }

        System.out.println("メソッド一覧");
        // メソッド一覧を取得
        final Method[] methods = classRamen.getDeclaredMethods();
        for (int index = 0; index < methods.length; index++) {
            final Method method = methods[index];
            System.out.println(" " + method.toString());
        }
    }
}

実行結果(コンソール出力)

フィールド一覧
 private java.lang.String Ramen.fSoup
メソッド一覧
 public java.lang.String Ramen.getSoup()
 public void Ramen.show()

 ラーメン・クラスに、どのようなフィールドやメソッドがあるのかが、表示されていますね。特別なjarファイルをクラスパスに追加などするまでもなく、このような芸当ができることもJava言語の特徴の1つです。

オブジェクト指向を「台無し」にしてしまうjava.lang.reflectパッケージ

 さらに、java.lang.reflectパッケージを利用すると、カプセル化により保護されているはずのオブジェクトの内容を、書き換えることもできてしまいます。ラーメンのトッピングを勝手に変えて、「いちごラーメン」を作ってみます。

TrickRamen.java
import java.lang.reflect.Field;

/**
* ねぎラーメン・オブジェクトを外から勝手にいじるクラス
*/

public class TrickRamen {
    public static void main(final String[] args)
    throws IllegalArgumentException, IllegalAccessException,
    SecurityException, NoSuchFieldException {
        // ラーメン料理人・インスタンスを作成する
        final RamenCook cook = new RamenCook();

        // ラーメン料理人にラーメンを注文する
        final IRamen ramen = cook.acceptLeekRamenOrder();

        final Class classRamen = ramen.getClass();

        // フィールドを取得
        final Field field
            = classRamen.getDeclaredField("fTopping");
        field.setAccessible(true);
        // privateフィールドの中身を勝手に外部から操作
        // この店では「いちごラーメン」は扱っていないはずなのに……

        field.set(ramen, "いちご");

        System.out.println("ラーメン・オブジェクトを確認");
        ramen.show();
    }
}

 上記のプログラムでは、「field.setAccessible(true);」を呼び出し、Java言語のアクセス修飾子とかかわりなく操作できるようにしてから、「field.set(ramen, "いちご");」を呼び出して、fToppingの値を書き換えています。

実行結果(コンソール出力)

ラーメン・オブジェクトを確認
ラーメンを表示
 トッピング: いちご
 スープ : とんこつ

 このラーメン屋では提供していないはずの、「いちごラーメン」が出来上がってしまいました。

図8 いちごラーメン
図8 いちごラーメン(こちらの図はJavaプログラミング[アプリケーション編]ステップアップラーニング』(技術評論社)で使われた図を引用して再作成したものです)

 このように、java.lang.reflectパッケージはオブジェクト指向を「台無し」にしてしまう力を併せ持っています。ですから、よほど特殊な目的を実現するプログラミングを行う場合でもない限り、java.lang.reflectパッケージは「利用してはいけない」APIである、ということも、Java言語によるプログラミングの常識なのです。

もっとオブジェクト指向を習得するためには?

 Java言語を使ってオブジェクト指向の基本概念を見てきましたが、いかがだったでしょうか。オブジェクト指向は難しくとっつきにくいものですが、これを使いこなすといろいろな応用ができることが期待できます。

 初心者のうちは、ほかの人やAPIなどがどのようにオブジェクト指向を扱っているのかを読む/知ることから学んでいくのが良い学習法だと思います。そして、オブジェクト指向の基本的な概念を理解したうえで、オブジェクト指向に関連する技術の中から、興味があるものにチャレンジしていってみましょう。

参考文献

@IT関連記事


“たい焼き”であま〜く理解するJava文法と言語仕様
携帯アプリを作って学ぶJava文法の基礎(3) 
初心者がJava言語を学ぶうえで最も困難なものの1つ、クラスやインスタンス、メソッドなどの概念をたい焼きで理解しましょう
Java Solution」フォーラム 2008/3/12
Javaのクラスとインスタンスを理解する
Eclipseではじめるプログラミング(7) オブジェクト指向言語にとってクラスは胆となるる部分です。今回は、簡単なクラスを作成しながらクラスを理解していきます
Java Solution」フォーラム 2005/3/19
Javaのインターフェイスを理解する
Eclipseではじめるプログラミング(10) オブジェクト指向言語のJavaにとってインターフェイスは必須の概念です。難しい理屈は抜きにして、実際に試して初歩を理解します
Java Solution」フォーラム 2005/7/13
Javaのパッケージを理解する
Eclipseではじめるプログラミング(11) 連載最終回はJavaのパッケージについて解説。連載第1回から今回までをマスターすれば、Javaの基本は理解できているはずです
Java Solution」フォーラム 2005/7/30
クラスを簡単に理解しよう
[連載]いまから始めるJava(3)
 クラスはJavaの学習で最初に難しいと感じるテーマ。ところが変数の使い方の観点から見ていくと、いとも簡単に理解できてしまいます
Java Solution」フォーラム 2003/1/30
クラスの継承の本質を知る
[連載]いま
から始めるJava(4) クラスの継承を抽象的に理解しようとすると難しくなってしまいます。メモリの拡張として理解すれば実に簡単であることが分かります
Java Solution」フォーラム 2003/3/8
メソッドの挙動を変えるオーバーライド
[連載]いまから始めるJava(8) 前回作成したHTMLパーサのメソッドの機能をオーバーライドを使い変更します。オーバーライドは同名のメソッドに異なる機能をもたせることができます
Java Solution」フォーラム 2003/8/16
クラスのメンバに利用制限を付与するアクセス制御
[連載]いまから始めるJava(9) 
外部から勝手にデータを変更されたり、参照されることからクラスのメンバを守るためには、アクセス制御を活用します

Java Solution」フォーラム 2003/9/17
Javaのクラスをグループ化するパッケージ
[連載]いまから始めるJava(10) 
パッケージとはクラスをグループ化し、クラスを扱いやすくするためのものです。すべてのクラスは必ずあるパッケージに属しています

Java Solution」フォーラム 2003/10/11
[連載]Javaオブジェクトモデリング
モデリングがきっちりできても、結局のところJavaのコードに落ちなければイミがない。UMLとJavaのマッピングについて連載開始!
【Javaオブジェクトモデリング INDEX】
ActionScriptで学ぶクラスやオブジェクト指向の基礎
Flashの基礎を無料で習得! ActionScript入門(4) 本格的なオブジェクト指向言語となったActionScript 3.0を通じてクラスやフィールド、メソッドなどの基本を学びましょう
リッチクライアント & 帳票」フ ォーラム 2008/4/9

プロフィール
伊賀 敏樹(いが としき)
ハンドル:いがぴょん

1968年生まれ。現在、NTTデータ ビジネスブレインズ 第一SI事業部 ソリューショングループ所属。システム開発の技術支援などに従事する。仕事におけるJava言語とのかかわりは1998年から。 現在、blanco Frameworkというオープンソースによるソースコード自動生成タイプの開発フレームワーク提供に取り組んでいる。 趣味はヴァイオリン演奏。アマチュアオーケストラで演奏することもある。

ホームページ
いがぴょんの日記ウェブページv2(1996年から続けているWeb日記)

所属団体
blanco Framework(コミッタ)

主な著書
やさしく学ぶ基礎からのJDBC
Javaプログラミング[アプリケーション編]ステップアップラーニング

1-2-3-4

 Index
第11回 いまさら聞けないJavaによるオブジェクト指向の常識
  Page1
いまこそ振り返る「オブジェクト指向」
Java言語で、オブジェクト指向を見てみよう
JavaにおけるClassとObject
  Page2
コラム 「オブジェクトとインスタンスは違うものなの?」
「汎化・特化」、Javaでは多くの場合「継承」
  Page3
「メッセージ・パッシング」、Javaではメソッド呼び出し
コラム 「同じ言葉でも意味が違う“インターフェイス”」
「カプセル化」、Javaではアクセス修飾子などで実現
「多態性」、同一のメッセージで異なる振る舞い
  Page4
Java APIの「裏技」java.lang.reflectパッケージとは?
もっとオブジェクト指向を習得するためには?





ご意見、ご感想はJava Solution 会議室へどうぞ


Java Solution全記事一覧



TechTargetジャパン

Java Solution フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

キャリアアップ

- PR -
@IT Sepcial

イベントカレンダー

PickUpイベント

- PR -
もっと見る
- PR -

お勧め求人情報

ホワイトペーパーTechTargetジャパン

@IT Sepcial
ソリューションFLASH