質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.90%

JavaのClassクラスについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 4,120
退会済みユーザー

退会済みユーザー

JavaのClassクラスについての質問です。
これを参考にしました。
http://qiita.com/SHOSI/items/ea713e6205257ab8617b

「全てのクラスのスーパクラスであるObjectクラスにgetClass()問いメソッドが実装されており、サブクラスのインスタンス生成時に該当のサブクラスのClass情報をClassクラスのインスタンスとして生成し、保持します。
また、同時にObjectクラスにはclassというpublic static finalフィールドが存在し、クラスロード時に生成され、String.classというようにすることで、対象のクラスのClassクラスを取得することができる。」

実際、String.classというふうにすれば、StringのClassクラスがえられるわけですが、Objectクラスを見ていても、classというフィールドが見当たりません。
また、
Class<?> str = String.class;

とすれば、classクラスのインスタンスが得られるというのもよくわかりません。
メソッドであれば返り値がそのインスタンスなんだろうと思いますが、フィールドでどうしてインスタンスが得られるのでしょうか。

また、isArray()メソッドについて、
この Class オブジェクトが配列クラスを表すかどうかを判定します
とリファレンスには書いているのですが、これってどういう意味なんでしょうか。
配列変数をフィールドに持つという意味ではないのですよね?

ご存知の方いらっしゃいましたら、回答お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

Objectクラスを見ていても、classというフィールドが見当たりません。 

元記事がフィールドと書いているのはわかりやすさのためなのかもしれませんが、
.class はJava言語仕様によればリテラルであり、10Lと書くとlongにしてくれるとかそういうことに近い感じですね。

http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.8.2

15.8.2. Class Literals

A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.


isArray()メソッドについては、配列かどうかがわかるのでどういう意味と言われてもそのままなんですけど、以下の様なコードであればわかるでしょうか。

import java.lang.reflect.Array;

public class IsArrayUsage {

    public static void main(String[] args){

        Object o = new int[]{ 1, 2 };
        printValue(o);

        o = "Hello world";
        printValue(o);
    }

    private static void printValue(Object o){
        // Objectが何だか知らないが、isArray()を使うと配列かどうか判断できる。
        if(o.getClass().isArray()){
            for(int i = 0; i < Array.getLength(o); i++){
                System.out.println(Array.get(o,i));
            }
        }else{
            System.out.println(o);
        }
    }
}

(一応言っておくと訳もなくObjectに入れるのはよくないコードです。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/11 20:48

    回答ありがとうございます。
    使い方については理解できましたが、Classインスタンスは「クラスの情報」が詰まったインスタンスではないのでしょうか。
    「現実世界にある一つのJavaクラス」を表していると思っていたのですが。。
    このコードだとフィールドに対して、それが配列であるかがboolean型として返ってきています。
    しかし、APIリファレンスを見ますと、「このClassクラスが配列クラスかどうかを判定できます。」と書いております。
    配列クラスが何かよくわかりませんが、「クラス」についてのものじゃないのでしょうか。


    すいません、もう一点あります。
    getClass()メソッドについてですが、呼び出すときに
    変数名.getClass()
    としていますね。
    この変数名はインスタンス変数じゃないといけないのではないでしょうか。
    flied_onionさんのコードはインスタンス化はしていないわけですが、エラーにもならずきちんと動作しますが、なぜでしょうか。

    キャンセル

  • 2016/08/11 21:26

    > Classインスタンスは「クラスの情報」が詰まったインスタンスではないのでしょうか。

    このあたりはドキュメントを見てくださいとしか言えないです。
    https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Class.html

    > Classクラスのインスタンスは、実行中のJavaアプリケーションのクラスおよびインタフェースを表します。列挙はクラスの一種、注釈はインタフェースの一種です。同様にどの配列も、同じ要素のタイプおよび次元数を持つすべての配列により共有されるClassオブジェクトとしてリフレクトされるクラスに属します。

    配列もクラスに属します。
    では、そのクラスが配列かどうかを見極める術はなにかということで、isArray()が用意されているというだけです。

    > この変数名はインスタンス変数じゃないといけないのではないでしょうか。

    変数名ですのでプリミティブ型(intなど)でない限りインスタンス変数でしかありえません(値がnullかどうかという話はありますが)。
    main関数で new したものを渡していますので、オブジェクトとして生成されたインスタンスです。
    インスタンス化していないというのはどこを指していますか?メソッド側でインスタンス化していないからということでしょうか。
    インスタンスをメソッド引数に渡せばインスタンスのままです。
    どういうエラーが起きると思いましたか?

    変数名.getClass() としたとき(なんらかのメソッドを呼び出している時)変数名の型がなんであれ(クラスであれインターフェースであれ)、
    * 呼び出したメソッドを持つものでなければならない
    * nullではならない(インスタンスが生成されていなければならない)
    という点は正しいです。

    上記コードでインスタンス変数ではないと感じるなら、いったんいろいろとコードを書いて感覚をつかんで見るのも手かと思います。

    キャンセル

  • 2016/08/12 23:59

    大方理解できました。
    配列もクラスに属するとのことですが、そうするとあるクラスの中に配列を用いた部分があれば、その状態は「クラスの中にクラスがある」という風に描写できるということになるのでしょうか。


    また、質問とは少しずれるのですが、ちょっと質問させてください。

    「main関数で new したものを渡していますので、オブジェクトとして生成されたインスタンスです。」
    なるほど、つまりoはObject型のインスタンスというわけですね。
    とすると、配列を作る時に使うnewというのはインスタンスを生成しているということでよろしいでしょうか。

    キャンセル

  • 2016/08/13 00:17

    > なるほど、つまりoはObject型のインスタンスというわけですね。

    違います。int[]のインスタンスを生成して、Object型参照変数 oに入れています。

    > 配列を作る時に使うnewというのはインスタンスを生成しているということでよろしいでしょうか。

    newキーワードは配列やオブジェクトを生成しています。

    このあたりの質問が出る状態であれば、やはり実際にコードを書いた方が良いと思います。理解を深めるにはそうした方が良いでしょう。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.90%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る