こんにちは。ハンドルネーム「Javaを復習する初心者」です。このサイトはプログラミング言語Javaの復習・学習をするブログです。プログラムの開発・実行はEclipseで行ってます。
スポンサーリンク
お知らせ
  • 参考文献のページ作りました。
  • Amazon.co.jpアソシエイトに参加していますが、参考文献の紹介はもしもアフィリエイトに統一しました。
  • 2016年10月9日からは投稿ペースを落とします。週1回くらいにする予定です。
スポンサーリンク

演算子instanceof

こんにちは。「Javaを復習する初心者」です。今回は演算子instanceofを使ってみました。

使い方

instanceofは「[対象のインスタンス] instanceof [クラスまたはインターフェース]」という使い方をします。結果はtrueかfalseになります。以下の場合、trueが返却されます。

  1. 指定したクラスのインスタンス
  2. 指定したクラスを継承したクラスのインスタンス
  3. 指定したインターフェースを実装したクラスのインスタンス

なのですが、明らかにfalseになるような状態はコンパイルエラーになるようです。例えば、以下のコードです。

        String s = "";
        System.out.println(s instanceof Integer);

String型のインスタンスはInteger型のインスタンスではありません。Eclipseで上記コードを書いた結果、「s instanceof Integer」に赤い波線が引かれ、「非互換条件オペランド型 String と Integer」というエラーが表示されました。

以下のコードはエラーになりません。trueが出力されます。

        GregorianCalendar c = new GregorianCalendar();
        System.out.println(c instanceof GregorianCalendar);

GregorianCalendar型のオブジェクトを生成し、それがGregorianCalendar型のインスタンスかチェックしています。trueになりました。冒頭のケース1です。

GregorianCalendarクラスはCalendarクラスを継承しています。なので次のコードもtrueになります。

        GregorianCalendar c = new GregorianCalendar();
        System.out.println(c instanceof Calendar);

これは冒頭のケース2です。 [子クラスのインスタンス] instanceof [親クラス]という言い方でも良いと思います。

StringクラスはCharSequenceインターフェースを実装したクラスです。そのため、以下のコードはtrueになります。

        String s = "";
        System.out.println(s instanceof CharSequence);

これは冒頭のケース3です。

冒頭の3ケースは以上のようになるのですが、他にも使われ方はありそうです。例えば、Object型変数を使う場合です。Object型は暗黙ですべてのクラスの親クラスです。なので、Object型変数にString型のインスタンスを格納することが可能です。

以下のコードはエラーにならず、実行することができます。trueを返却します。

        Object s = "";
        System.out.println(s instanceof String);

上記のStringをIntegerに変えてもエラーにならず、実行することができます。その場合falseを返却します。

使う場面の例

さて、instanceofはどのような場面で使うのでしょうか。もし、以下のようにObject型を返却するメソッドを使う場合、instanceofを使うことがあるかもしれません。以下は引数が偶数か奇数かでStringまたはIntegerのインスタンスを返却します。

    private static Object test(int i) {
        if (i % 2 == 0) {
            return "Hello." + i;
        } else {
            return new Integer(1);
        }
    }

このメソッドから返却されたオブジェクトをString型へキャストしようとした場合、引数によってはInteger型をString型にキャストすることになり、「ClassCastException」が発生します。なので、以下のようにinstanceofを使用します。

        for (int i = 0; i < 5; i++) {
            String s = null;
            Object o = test(i);
            if (o instanceof String) {
                s = (String)o;
            }
            System.out.println(s);
        }
Hello.0
null
Hello.2
null
Hello.4

上記のように正常にプログラムが終了します。