Javaでオブジェクトを複製する
質問
Javaで変数を変更しても、その元になった変数は変更されないことを知りました。
int a = new Integer(5);
int b = a;
b = b + b;
System.out.println(a); // 5 as expected
System.out.println(b); // 10 as expected
オブジェクトについても同じようなことを想定しました。このクラスについて考えてみましょう。
public class SomeObject {
public String text;
public SomeObject(String text) {
this.setText(text);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
このコードを試した後、私は混乱しました。
SomeObject s1 = new SomeObject("first");
SomeObject s2 = s1;
s2.setText("second");
System.out.println(s1.getText()); // second as UNexpected
System.out.println(s2.getText()); // second as expected
なぜ、どちらかのオブジェクトを変更すると、もう一方のオブジェクトに影響を与えるのか、説明してください。変数textの値は、両方のオブジェクトのメモリ上の同じ場所に格納されていることは理解しています。
変数の値は独立しているのに、オブジェクトの値は相関しているのはなぜでしょうか?
また、単純な代入ではうまくいかない場合、どのようにSomeObjectを複製するのでしょうか?
どのように解決するのですか?
Javaではすべての変数が 参照 . ですから
SomeClass s2 = s1;
を指定するだけです。
s2
と同じオブジェクトに
s1
が指すのと同じオブジェクトに代入しています。実際には、参照 s1 の値 (これは
SomeClass
のインスタンスを指している)参照 s1 の値を s2 に代入していることになります。
を変更した場合
s1
,
s2
も同様に修正されます。
(も修正されます(同じオブジェクトを指しているため)。
例外として、プリミティブ型があります。
int, double, float, boolean, char, byte, short, long
. これらは値で保存されます。ですから
=
を使用する場合、値を代入するだけで、同じオブジェクトを指すことはできません(参照ではないため)。これは次のことを意味します。
int b = a;
の値を設定するだけです。
b
の値を
a
.
を変更した場合
a
,
b
は変わりません。
結局のところ、すべては値による代入であり、それは参照の値であって、オブジェクトの値ではありません(上記のようにプリミティブ型の例外を除いて)。
ですから、あなたの場合、コピーを作るなら
s1
をコピーしたい場合は、このようにします。
SomeClass s1 = new SomeClass("first");
SomeClass s2 = new SomeClass(s1.getText());
あるいは、コピーコンストラクタを
SomeClass
に追加して、インスタンスを引数として受け取り、それを自分自身のインスタンスにコピーすることもできます。
class SomeClass {
private String text;
// all your fields and methods go here
public SomeClass(SomeClass copyInstance) {
this.text = new String(copyInstance.text);
}
}
これで、かなり簡単にオブジェクトをコピーすることができます。
SomeClass s2 = new SomeClass(s1);
関連
-
アクセス制限です。タイプ 'Application' は API ではない(必要なライブラリに制限がある)。
-
メモ帳でJavaプログラムをコンパイルして実行すると、Could not find or load main class ...というエラーが表示される。解決方法
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
メモ帳でJavaプログラムをコンパイルして実行すると、Could not find or load main class ...というエラーが表示される。解決方法
-
Javaジェネリックを1つの記事で
-
java.sql.SQLException: 結果セットの開始前
-
Java appears タイプEを囲むインスタンスがアクセスできない。
-
XXX型を囲むインスタンスがJavaでアクセスできない
-
代入の左辺は変数でなければならない 解答
-
Javaがエラーで実行される、選択が起動できない、最近起動したものがない
-
org.xml.sax.SAXParseExceptionのエラー解決方法
-
アクセス制限の解決方法: ---- in Java
-
[解決済み] コンストラクタでオーバーライド可能なメソッド呼び出しの何が問題なのでしょうか?