2

これが以前に発生した場合は申し訳ありませんが、これに関する別のスレッドは見当たりませんでした。しかし、もしあれば、私にリンクを教えてください。

ここに簡単なプログラムがあります。実行すると、「 6 4 」が出力されます

public static void main(String[] args) {
    Foo foo = new Foo();
    foo.t = 6;
    foo.f = 4;

    Bar b = new Foo();

    ArrayList<Bar> list = new ArrayList<Bar>();
    list.add((Bar) foo);

    Foo foo2 = (Foo) list.get(0);

    System.out.println(foo2.t + " " + foo2.f);
}

static class Bar {
    int t;
}

static class Foo extends Bar {
    int f;
}

これは奇妙に思えます。リストに Foo を追加すると、f を持たないバーがリストに含まれているため、f フィールドが削除されると思うからです。

しかし、バーにキャストされた後、 f が固執しているようです。誰かがこれがなぜなのか説明できますか?

4

5 に答える 5

6

n回キャストしてアンキャストしても、実際のオブジェクトは同じままです。
キャストは、オブジェクト属性を追加/削除/変更することはありません。

Bar b = new Foo();

ここで参照はタイプBarで、実際のオブジェクトはタイプFooです。As FooextendsBarは、属性ft(Inherited from Bar) も持つことを意味します。

list.add((Bar) foo);  

ここでは Bar (Upasting) にキャストしていますが、実際のオブジェクトは変更されていません。

(Foo) list.get(0);

ここでは、との元の値を持つFooタイプのまだオブジェクトにキャストし直しています。Footf

于 2013-02-07T06:21:29.903 に答える
2

ポリモーフィズムがどのように機能するかではありません。特定のオブジェクトからは何も削除されません。あなたはそれについてこのように考えることができます:

  • メモリ内に実際のオブジェクトがあります
  • このオブジェクトへのさまざまな参照を持つことができます:Foo、Bar、Objectなど。
  • 実際のオブジェクトは参照を気にしません-新しい参照を作成しても変更されません
  • ただし、各参照は、この参照によってオブジェクトにアクセスできる方法を決定します。

Fooのすべてのインスタンスは、Barのインスタンスとして扱うことができます。ただし、明示的にキャストした後は、このインスタンスを再びFooとして操作できます。元々Barだった場合、このキャストはランタイムで失敗します。

于 2013-02-07T06:29:04.103 に答える
1

Java では、フィールドは多態的ではありません。

それがあなたがそれについて混乱している理由です。

したがってFoo、リストに追加してfも、実際には のオブジェクトとして存在しますFoo

以下は Code Ranch からの抜粋です - by Jim Yingst

それはJavaの設計によるものですか、それとも制限ですか、それとも私の誤解ですか?

それは設計によるものです。フィールドを動的に解決すると、実行が少し遅くなります。フィールドを非公開にして、動的に解決されるメソッドでアクセスできるため、必要な理由はまったくありません。そのため、フィールドは代わりにコンパイル時に解決されます。

于 2013-02-07T06:21:51.870 に答える
0

スーパークラス変数に型キャストする場合と同様に、オブジェクトのサブクラスプロパティにアクセスすることはできませんが、オブジェクトはそのまま残ります。を公​​開するラッパーだけget() and set() methodsが変更されます。getter-setterサブクラスメソッドAPIを表示することはできません。ただし、キャストバックをサブクラスに入力すると(基本的にはアンラップ)、サブクラスのゲッターセッターメソッドが再び表示されます。

オブジェクトは常に変更されていません。

于 2013-02-07T06:28:10.677 に答える
0

前の回答への重要な追加:オブジェクトをリストに追加しても、そのオブジェクトはまったく変更されません。したがって、オブジェクトに属性があった場合、それはそのまま残ります。

残りの混乱は、ポリモーフィズムと呼ばれる機能です。FooはBarであるため、いつでもBarとして扱うことができますが、Fooは変更された(拡張された)Barであるため、標準のBarオブジェクトとは異なる動作をする場合があります。

お役に立てば幸いです。

于 2013-02-07T06:28:00.307 に答える