0

Person別のクラスの一般化であるというクラスがあると想像してみましょうMan。このクラスのインスタンスをいくつか作成する場合

Man man = new Man();
Person person = new Man();

ここで、変数から参照されているインスタンスのコンパイル時クラスmanManであり、personのコンパイル時クラスはPersonであり、両方のインスタンスの実行時クラスはですMan。これまでのところ、実行時に作成されるインスタンスは両方ともクラスであるため、用語を完全に理解していますMan。しかし、次のようにmanインスタンスをキャストする場所を指定すると

Person personMan = (Person) man;

なぜ実行時型personManはまだ人間なのですか?インスタンスのランタイムクラスは、新しいインスタンスが作成されたときにのみ設定されますか?また、実行時に変数のコンパイル時クラスを実際に取得する方法があるので、personManのクラスのタイプを照会できます(getClassは)を返しManます。

編集:「クラスのコンパイル時クラス」は間違いでした(そしてあまり意味がありません)。私が意味したのは可変でした(したがって、彼らはpersonManがどのタイプのクラスであるかについて質問します:))

4

3 に答える 3

5

ここでは、3つの異なる概念を区別することが重要です。

  • 変数manperson
  • 参照(変数の値)
  • オブジェクト(参照、ええと、参照するメモリのブロブ)

オブジェクトのタイプは、作成後に変更されることはありません。別の型への参照をキャストすると、その式のコンパイル時の型にのみ影響します。参照型キャスト式の結果は、常に元の参照と同じです。それでも、同じ型を持つ同じオブジェクトを参照します。(それはボクシングを脇に置いたままです-そしてもちろん、キャストは実行時に失敗し、例外につながる可能性があります。)

また、実行時にクラスのコンパイル時クラスを実際に取得する方法はありますか?

変数のコンパイル時の型を意味する場合-それがローカル変数である場合ではなく、バイトコードを実際に詳細に検査する必要があります。フィールドの場合は、リフレクションを使用して取得できます。なぜ知りたいんですか?

于 2012-11-01T13:45:30.297 に答える
1

ランタイムタイプは、新しいタイプです。new Man()は、格納する変数のタイプに関係なく、常にManです。

コンパイル型は、宣言された変数の型です。

あなたの例では

Person personMan = (Person) man;

personManのメソッドと属性でのみコーディングできます。あなたもすることができます

((Man)personMan).someManMethod();

ただし、personMapがManのインスタンスを保存していない場合、これによりエラーが発生する可能性があります。

于 2012-11-01T13:48:02.657 に答える
1

Javaでは、変数(プリミティブ以外)は単なるオブジェクトへの参照です。オブジェクト自体は別の場所にあり、直接アクセスすることはできません。

いずれの場合も、Manオブジェクトはどこかにあり、さまざまな参照によって、そのManオブジェクトの機能のさまざまなサブセットにアクセスできます。

于 2012-11-01T13:48:12.590 に答える