web-dev-qa-db-ja.com

変数、オブジェクト、参照の違いは何ですか?

変数オブジェクト、および参照の違いは何ですか?

たとえば、それらはすべて特定の型を指し、すべて値を保持する必要があります(もちろん、一時的なnullが可能な型を持っている場合を除きます)が、それらの機能と実装は正確にどのように異なりますか?

例:

Dog myDog = new Dog(); //variable myDog that holds a reference to object Dog
int x = 12; //variable x that hold a value of 12

それらは同じ概念を持っていますが、どのように異なっていますか?

68
user5217533

(明確にするために、ここで説明するのはJavaとC#に固有のものです。他の言語にも当てはまるとは思わないでください。

私は自分がどこに住んでいるのかを誰かに伝えるのに似ています。住所を紙に書きます。

  • 変数は紙のようなものです。値を保持しますが、それ自体は値ではありません。そこにあるものをすべて消して、代わりに何かを書くことができます。
  • 私が紙に書いた住所は参照のようなものです。それは私の家ではありませんが、私の家へのナビゲーションの方法です。
  • 私の家自体は物のようなものです。同じオブジェクトへの複数の参照を提供できますが、オブジェクトは1つしかありません。

それは役立ちますか?

値型と参照型の違いは、紙に書かれているものです。たとえば、ここに:

int x = 12;

12の数字が直接書かれた紙を持っているようなものです。一方、

Dog myDog = new Dog();

dogオブジェクトのコンテンツ自体を紙に書き込みません。新しいDogを作成し、その紙に犬への参照を書き込みます。

アナロジー以外の用語で:

  • 変数は、メモリ内の保存場所を表します。コンパイル時に参照できる名前があり、実行時には値があり、常にコンパイル時の型と互換性があります。 (たとえば、Button変数を持っている場合、値は常にButton型のオブジェクトへの参照、サブクラス、またはnull参照になります。
  • オブジェクトは、一種の独立したエンティティです。重要なのは、変数または式の値がneverオブジェクトであり、参照のみであることです。オブジェクトは実質的に次のもので構成されます。
    • フィールド(状態)
    • 型参照(オブジェクトの存続期間中に変更することはできません)
    • モニター(同期用)
  • 参照とは、オブジェクトにアクセスするために使用される値です。メソッドを呼び出したり、フィールドにアクセスしたりします。通常、.演算子を使用して参照をナビゲートします。たとえば、fooPerson変数である場合、foo.getAddress().getLength()foo(参照)の値を取り、その参照するオブジェクトでgetAddress()を呼び出します。を指します。結果はString参照になる可能性があります...次に、that参照が参照するオブジェクトでgetLength()を呼び出します。
150
Jon Skeet

これらの概念を説明するとき、私はしばしば次の類推を使います。


オブジェクトが風船だと想像してください。変数は人です。すべての人はvalue typeチームまたはreference typeチームに属します。そして、彼らは皆、以下のルールで小さなゲームをします:

値の種類のルール:

  • 空気で満たされた風船を腕に抱えています。 (値型変数はオブジェクトを格納します。)
  • 常に1つのバルーンを保持する必要があります。 (値の型はnull値を許可しません。)
  • 他の誰かがあなたの風船を望んでいるとき、彼らは自分の同じ風船を爆破し、それを彼らの腕に保持することができます。 (値の型では、オブジェクトがコピーされます。)
  • 二人は同じ風船を持てません。 (値の型は共有されません。)
  • 別の風船を持ちたい場合は、既に持っている風船をポップして別の風船をつかむ必要があります。 (値型オブジェクトは置換されると破棄されます。)

参照タイプのルール:

  • ヘリウムで満たされたバルーンにつながる文字列を保持することがあります。 (参照型変数はオブジェクトへの参照を格納します。)
  • 1つの文字列を保持することも、まったく保持しないこともできます。 (参照型変数はnull可能です。)
  • 他の誰かがあなたの風船を望んでいるとき、彼らはあなた自身のひもを手に入れて、あなたが持っているのと同じ風船に結び付けることができます。 (参照タイプでは、参照がコピーされます。)
  • 複数の人が、すべて同じ風船につながる文字列を保持できます。 (参照型オブジェクトは共有可能)
  • 特定のバルーンに紐を保持している人が少なくとも1人いる限り、バルーンは安全です。 (参照型オブジェクトは到達可能である限り生きています。)
  • 特定のバルーンの場合、誰もが最終的に手放すと、そのバルーンは飛び去り、誰もそれに到達できなくなります。 (参照型オブジェクトはある時点で到達不能になる可能性があります。)
  • ゲームが終了する少し後の時点で、大気圧のために失われた気球が自然に飛び出すことがあります。 (到達不能オブジェクトはガベージコレクションの対象であり、これは非決定的です。)

質問に答えるようなものと考えることができます。

オブジェクトは何ですか...
それは、世界の物理的なもののように、それ自体が認識可能であり、他の「もの」と区別する重要な特性を持つ「もの」です。あなたが知っているように、犬は犬がisえるので犬であり、投げると尾を動かし、ボールを追います。

変数とは...
自分の手を見るように。それぞれが手そのものです。皮膚には指、爪、骨がありますが、一方は左手で、もう一方は右手です。つまり、同じタイプ/種類の2つの「もの」を持つことができますが、それぞれが独自の方法で異なり、異なる値を持つことができます。

参照は...です
通りにある2つの家を見ると、それぞれのファサードがありますが、それぞれ1つの固有の住所でそれぞれに到達できます。つまり、3ブロック先または別の国では、家の住所を伝えることができます。直接指さなくても、家を置いた場所に残っているからです。

プログラミングのために、C++の方法の例

class Person{...}
Person Ana = new Person(); //An object is an instance of a class(normally)

つまり、アナは人ですが、彼女は他の人と区別するユニークな特性を持っています。

&Ana //This is a reference to Ana, that is to say, a "where" does the variable 
     //"Ana" is stored, wether or not you know it's value(s)

Ana自体は、「Ana」という名前の人のプロパティを保存するための変数です

7
Edgar Sampere

ジョンの答えは、類推からアプローチするのに最適です。より具体的な言葉遣いがあなたに役立つなら、私はピッチングすることができます。

変数から始めましょう。変数は、値を含む[名前付き]ものです。たとえば、int x = 3は、整数3を含むxという名前の変数を定義します。その後、割り当てx=4を追加すると、xには整数4が含まれるようになります。 '変数を置き換えません。新しい「値が現在4である変数x」はありません。xの値を新しい値に置き換えただけです。

それでは、オブジェクトに移動しましょう。多くの場合、多くの場所から1つの「もの」を参照する必要があるため、オブジェクトは便利です。たとえば、エディターでドキュメントを開いてプリンターに送信する場合、エディターとプリンターの両方で参照されるドキュメントが1つだけであると便利です。必要以上に何度もコピーする必要がなくなります。

ただし、2回以上コピーする必要はないため、オブジェクトを変数に入れることはできません。変数は値を保持するため、2つの変数がオブジェクトを保持する場合、変数ごとに1つずつ、2つのコピーを作成する必要があります。参照は、これを解決する中間的なものです。参照は、変数に格納できる小さなコピーしやすい値です。

したがって、コードでDog dog = new Dog()と入力すると、new演算子は新しいDogオブジェクトを作成し、そのオブジェクトへの参照を返すため、変数に割り当てることができます。割り当ては、dogに、新しく作成されたオブジェクトへの参照の値を与えます。

6
Cort Ammon

new Dog()はオブジェクトDogをインスタンス化します。つまり、オブジェクトのメモリを作成します。一部の操作を操作するには、変数にアクセスする必要があります。そのためには、Dog myDogという参照が必要です。オブジェクトを印刷しようとすると、アドレス以外の読み取り不能な値が印刷されます。

      myDog -------> new Dog().
3
Shriram