0
0

More than 1 year has passed since last update.

配列のclone()の挙動確認というか覚書

Posted at

シャローコピーとディープコピー。え、ディープなコピーがあるってことはシャローなコピーの時ってどうなんだろう?あれ、シャローコピーって配列だけで要素空なんだっけ?

きっとしばらくすると忘れちゃうんだ。その度に、コードで検証するけどとっても労力がもったいない。ここを見て思い出せ自分。

配列のclone()の結論。

  • 配列はインスタンスの複製
  • 要素は値のコピー
サンプルコード
/**
 * 配列に対するclone()の挙動確認
 * 
 * 配列は複製。
 * 要素は値コピー。
 */
public class Sample0216a
{
	public static void main(String[] args)
	{
		//clone()した直後の中身が同じであるにも関わらずhash値が異なることから、配列のインスタンスは別物と言える。
		//要素はコピーなのか、複製が代入されたものなのかはここからは判断できない。
		System.out.println("+++sample1+++");
		sample1();
		System.out.println();
		
		//ls1[0]の値がls2[0]と同じなので、これらは同じインスタンスであると言える。
		//要素は値コピーされている。
		System.out.println("+++sample2+++");
		sample2();
		System.out.println();
		
		return;
	}
	
	static void sample1()
	{
		final int[] ls1 = new int[]{0, 1, 2, 3, 4, 5};
		int[] ls2 = null;
		String s1 = null;
		
		s1 = Arrays.toString(ls1);
		System.out.print("ls1: ");
		System.out.print(s1);
		System.out.print("/");
		System.out.println(System.identityHashCode(ls1));
		
		ls2 = (int[])ls1.clone();
		s1 = Arrays.toString(ls2);
		System.out.print("ls2: ");
		System.out.print(s1);
		System.out.print("/");
		System.out.println(System.identityHashCode(ls2));
		
		System.out.println();
		
		ls2[0]++;
		System.out.println("ls2[0]++");
		System.out.println();
		
		s1 = Arrays.toString(ls1);
		System.out.print("ls1: ");
		System.out.print(s1);
		System.out.print("/");
		System.out.println(System.identityHashCode(ls1));
		
		s1 = Arrays.toString(ls2);
		System.out.print("ls2: ");
		System.out.print(s1);
		System.out.print("/");
		System.out.println(System.identityHashCode(ls2));
		
		return;
	}
	
	
	static void sample2()
	{
		final AtomicInteger[] ls1 = new AtomicInteger[]{new AtomicInteger(0), new AtomicInteger(1), new AtomicInteger(2), new AtomicInteger(3), new AtomicInteger(4), new AtomicInteger(5)};
		AtomicInteger[] ls2 = null;
		String s1 = null;
		
		s1 = Arrays.toString(ls1);
		System.out.print("ls1: ");
		System.out.println(s1);
		
		ls2 = (AtomicInteger[])ls1.clone();
		s1 = Arrays.toString(ls2);
		System.out.print("ls2: ");
		System.out.println(s1);

		System.out.println();
		
		ls2[0].incrementAndGet();
		System.out.println("ls2[0].incrementAndGet()");

		System.out.println();
		
		s1 = Arrays.toString(ls1);
		System.out.print("ls1: ");
		System.out.println(s1);
		s1 = Arrays.toString(ls2);
		System.out.print("ls2: ");
		System.out.println(s1);
		
		return;
	}
}
結果
+++sample1+++
ls1: [0, 1, 2, 3, 4, 5]/1933863327
ls2: [0, 1, 2, 3, 4, 5]/112810359

ls2[0]++

ls1: [0, 1, 2, 3, 4, 5]/1933863327
ls2: [1, 1, 2, 3, 4, 5]/112810359

+++sample2+++
ls1: [0, 1, 2, 3, 4, 5]
ls2: [0, 1, 2, 3, 4, 5]

ls2[0].incrementAndGet()

ls1: [1, 1, 2, 3, 4, 5]
ls2: [1, 1, 2, 3, 4, 5]

シャローコピーがこの挙動ということは、ディープコピーは要素も複製するんだよね。複製するのにコピーって言われると混乱するのは自分だけだろうか。いい覚え方があるのかな?

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0