コピーには浅いコピーと深いコピーがあり、変数の型によって異なるため注意が必要です。
Javaの場合、どのように気をつけるといいかを書きます。
浅いコピー
実体(インスタンス)への参照をコピーします。
実体Aへの参照aをコピーして参照bを作ったとすると、
参照bで実体Aを操作すれば、参照aで実体Aを参照したとき、その影響を受けます。
主に参照型の変数(Javaなら型名の頭文字が大文字のものや、リストなど)で代入やcloneメソッドを使うとこの現象がおきます。
それを回避するには、
String text1 = "aaa"; String text2 = text1; //参照のコピー text2 = new String(text2); //新しいインスタンスを生成
のように新しくインスタンスを作り直すことが必要です。
深いコピー
実体(インスタンス)そのものを複製します。
そのため、複製した実体を変更しても、複製元の実体には影響が及びません。
普通に代入、cloneしても深いコピーになるのはプリミティブ型の変数です。
具体的には、
- byte
- short
- int
- long
- char
- float
- double
- boolean
の8つです。
言語によって少し仕様が異なるようです。
例えばPythonでは、引数には全て参照が渡されます。
しかし、参照が渡されたあと、その関数内で値が変更されたとき、渡した値自体が変更されるかはオブジェクトのタイプによります。
- Immutable :int,float,str等
- Mutable :list,dict等
Immutableはコピー先で値を変更してもコピー元に影響は及ばないのですが、
Mutableではコピー先で値を変更するとコピー元にも変更が反映されます。
これを回避するためには、copyモジュールのdeepcopy()関数を用いればオーケーです。
コードを書く時には常に意識しないと思わぬエラーにぶつかってしまいます。