0

私はJavaが初めてで、より優れた従来のプログラミングとは何かを知りたいです。

既存のオブジェクトの属性を変更したい場合:

set1 つの方法は、単純に関数で値を設定することで、より効果的です。

anExistVar.setX(newValue);
anExistVar.setY(2);
anExistVar.setSomething(null);

もう 1 つの方法は、(オーバーライドで) 新しいオブジェクトを作成することです。よりエレガントで明確に見えます (ガベージ コレクターにいくつかの作業を任せます...):

anExistVar = new SomeClass(newValue, 2, null);

多分答えは、変更する必要がある値の数によって異なりますか? この場合、効率に大きな違いはないのでしょうか?

(私の質問は、システムが動的メモリを管理するJAVAまたは任意の言語を指します)

この件に関するいくつかの議論を読みましたが、決定的な答えは得られませんでした。

前もって感謝します!

4

5 に答える 5

1

2 番目の方法では、いくつかの利点がある不変オブジェクトを使用できます。たとえば、不変オブジェクトは変更できないため、それらをコピーする必要はありません。これは、状況によってはより効率的です。これにより、値を変更する必要があるたびに新しいオブジェクトを作成する必要がありますが、ライフサイクルの短いオブジェクトは gc によって効率的に収集されます。

Haskell などの一部の言語には、不変のオブジェクトしかないことに注意してください。

于 2013-04-06T21:37:22.793 に答える
0

答えは、実際にここで何をしようとしているのかに依存すると思います。概念的には、基本的な問題は、プログラマーはメンバーを更新した後、またはプログラム内の根本的に新しいエンティティとして完全に再割り当てした後の状態を考えているかということです。それとも単に古いものの修正版ですか?anExistVar

単に変更されたバージョンである場合、なぜすべてのメンバー変数を一度に更新するのですか? 古いオブジェクトと新しいオブジェクトは同じ名前とメモリの場所を共有していますが、論理的にはそれらの間に何の関係もないようです。ただし、すべてのメンバー変数を更新するつもりでそれを怠ると、古い状態と新しい状態の間に関係がないと考えられ、古い状態からのホールドオーバーがあることに気付かない可能性があることに注意してください。特に、対応する public を持たない private メンバー変数が存在する場合があります。setメソッドであるため、たとえそれが意図されていても、オブジェクトを完全に変換できない場合があります。要するに、オブジェクトのこの種の急進的な変換は、何をしているのか、なぜ行っているのか、あるいは実際に成功するかどうかがすぐにはわからないため、混乱を招きます。ただし、変更されたオブジェクトがまだ本質的に同じオブジェクト (たとえば、元のデータの一部を含む) であると思われる場合は、部分的に忠実なコピーを作成するよりも、既存のオブジェクトを変更する方がはるかに理にかなっています。

new根本的に新しいものを作成している場合は、オブジェクトとして宣言するのがおそらく最善です。古いオブジェクトと新しいオブジェクトの間に何らかの関係staticを持たせたい場合は、インスタンス化されたそのクラスのインスタンスの総数を追跡するためのクラス メンバーなど、使用できるさまざまな手法があります。 . または、新しいインスタンスの構築を古いインスタンスの public 属性によって部分的に決定する場合は、それらの属性をコンストラクターに明示的に渡します。

効率性とガベージ コレクターに関する限り、おそらくどちらの方法でも心配する必要はありません。ガベージ コレクタのポイントは、明示的に何かを削除する負担からプログラマを解放することです。その動作を明示的に制御することはできず、十分に効率的に動作するため、実際に心配する必要はありません。メモリ不足は、ガベージ コレクタの過負荷よりも懸念事項です。あなたが説明している特定のケースでは、はい、ガベージコレクターは古いオブジェクトを削除する必要がありますが、コレクターの効率に大きな影響はありません。不要になったオブジェクトへの参照を維持するのは問題があります。後でそれらを参照する場合に、ガベージ コレクターがそれらのオブジェクトを収集できないためです。それはあなたのものではないので」プログラミングおよび論理的な観点から最も明確です。

于 2013-04-06T21:43:53.570 に答える
0

それはあなたが望むものに依存しませんか?最初のスニペットは既存のオブジェクトを変更し、2 番目のスニペットは新しいオブジェクトを作成します。同じオブジェクトへの参照では、バージョン 1 では新しい値が表示されますが、バージョン 2 では表示されません。

とにかく参照が 1 つだけの場合: 最初の参照はより冗長であるため、理解しやすい可能性があります。さらに、コンストラクターは必要なものだけを取得する必要があります。(それがなければ、オブジェクトは役に立たないでしょう) オーバーロードされたコンストラクターが多すぎると、混乱しやすくなります。すべての割り当てを明示的に綴ったほうがよいと思います。

于 2013-04-06T21:39:23.707 に答える
0

古い属性値を持つ古い oblect が必要ない場合は、それを変更してください。慣習はそれを変えることです。そうしないと、レビュアーはあなたがなぜそれをしたのかを調べようとします。古いオブジェクトが現在どこで使用されているのか疑問に思うでしょう。より明確なコードを作成することがより重要です。

メモリとガベージ コレクターの一時停止は、このように多くの場所、多くの要求、またはループ内にある場合に問題になります。要するに、機能が許せばオリジナルを変更する

于 2013-04-06T21:42:17.373 に答える