web-dev-qa-db-ja.com

SunのエンジニアがJava値のみを呼び出すことにしたのはなぜですか?

彼らがCallby Valueを採用することに決めた特別な理由はありますか?簡単にするためですか?

2
java_mouse

「CallbyValue」および「CallByReference」という用語は、プログラマーによって少し緩く使用されることがあり、これらの用語の使用は、必ずしも根本的な現実を反映しているわけではありません。

誰かがCallByValueとCallBy Referenceを参照しているのを聞いたとき、彼らが通常言っているのは、プリミティブ値はCall By Valueであるのに対し、オブジェクトはCall ByReferenceであるということです。パラメータを値で渡すと、常に元の値が返されるため、違いがわかります。つまり、値で呼び出すと、関数は実際のプリミティブではなく、プリミティブのcopyを取得します。*

参照による呼び出しは異なります。参照で呼び出すと、渡すオブジェクトcanは関数によって変更され、関数が戻ったときにオブジェクトはそれらの変更を保持します。 Javaは次のように機能します。関数に渡されたオブジェクトは、関数によってオブジェクトに加えられた変更を保持します。

では、なぜJava参照による呼び出しではないのですか?

なぜなら、オブジェクトを関数のパラメータリストに渡すとき、実際には参照によってオブジェクトを渡すわけではないからです。実際に行っているのはオブジェクトへの参照を値で渡す

これは髪の毛を裂くように見えるかもしれませんが、考えてみてください。 Javaは、プリミティブの場合と同様に、オブジェクトを渡す前にオブジェクトのコピーを作成しますか?いいえ。参照のコピーを作成し、それを関数に渡します。変更できますか?別のオブジェクトを指し、関数が戻ったときに変更が保持されることを期待するための参照?いいえ、できません。

プリミティブを含む変数が関数パラメーターとして渡される場合、実際の変数ではなく、変数のが渡されます。 数式が関数に渡されると、式が最初に評価され、結果が値によって関数に渡されます。

10
Robert Harvey

JavaはObjective-Cの影響を強く受けています。 Objective-CはSmalltalkの影響を強く受けています。 SmalltalkはLISPの影響を強く受けています。それらはすべて値による呼び出しです。

または、より具体的には、それはオブジェクトごとの共有(別名、共有ごとの呼び出しまたはオブジェクトごとの呼び出し)であり、値が値へのポインタである値による呼び出しの特殊なケースです。 (潜在的に変更可能な)オブジェクト。

プリミティブの場合、Javaは実際にはポインターなしで値による呼び出しを使用しますが、プリミティブは不変であるため、とにかく違いを区別することはできません(2つのポインターがある場合にのみ違いを観察できます)。可変オブジェクトへの変換と、あるポインターをたどることによって実行される突然変異は、別のポインターをたどることによって観察できますが、プリミティブは可変ではありません。)

だから、あなたの質問に答えるために:歴史と遺産。

8
Jörg W Mittag

Javaには、少数の事前定義された値タイプの値による呼び出しと、オブジェクトタイプの参照による呼び出しがあります。 [参照は内部的に値によって渡されるポインターですが、それは重要ではありません。]

C#(Java 3.0の一種))にはoutパラメーターとrefパラメーターがありますが、Javaはありませんコンパイラの作成者として、私はそれらが本当に物事を複雑にしていると言うことができます。ボクシングにつながるポインタメカニズム(オブジェクトと同様)を使用するかどうか、コピーインコピーアウトを使用するかどうかを決定する必要があります。エイリアシングの問題。変数が初期化されているかどうかを追跡する方法。Java設計者は、これは非常に難しいか、価値がないと思っていたと思います。

Javaによって行われた実際の決定は、値型を第一級市民として扱うことではありませんでした。ユーザー定義の値型はなく、ボクシングはなく、値を渡すだけです。C#では、価値があると考えられていました。しかし、Javaでは、プリミティブ値とユーザー定義オブジェクトで十分だと考えていました。私はC#を好みますが、outまたはrefパラメーターを使用することはほとんどありません。

編集:私の弁護では、1960年代以降、参照による呼び出しはさまざまな戦略を説明するために使用されてきました。ここでの私の使用法は境界線であり、純粋主義者を怒らせます。オブジェクトがコピーされないという意味で使用しますが、渡されたオブジェクトに変更を加えると元のオブジェクトに影響します。ただし、渡されたパラメータへの割り当ては、元のオブジェクトに影響を与えず、代わりに新しいオブジェクト(またはnull)を参照します。

0
david.pfx