BBH
-Biz Branding Hub-
投稿日 : 
2020/06/28
更新日 : 
2020/06/28

【Java】Listの複製時のメモリ割り当ての検証

JavaでListを複製する場合は、

List<T> list = new ArrayList<>(List<T>);


で可能。

その際、複製されたListは別のメモリ領域が割り当てられ、別オブジェクトとなる。

Listの複製検証

List list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");

// List複製
List list2 = new ArrayList<>(list);
list2.add("ZZ");

// List複製
List list2 = new ArrayList<>(list);
list2.add("ZZ");

System.out.println(list);
// →[A, B, C]

System.out.println(list2);
// →[A, B, C, ZZ]

// 別インスタンスであることを確認
System.out.println(list==list2);
// →false

オブジェクトの配列を使用した時の挙動は以下。

Listの複製検証(オブジェクト型)

import java.util.*;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws Exception {
        
        List<customObj> objList = new ArrayList<>();
        objList.add(new customObj(1, "1"));
        objList.add(new customObj(2, "2"));
        objList.add(new customObj(3, "3"));
        
        List<customObj> objList2 = new ArrayList<>(objList);
        objList2.add(new customObj(4, "4"));
        
        
        System.out.println(objList);
        // → [Main$customObj@36baf30c, Main$customObj@7a81197d, Main$customObj@5ca881b5]
        
        System.out.println(objList2);
        // → [Main$customObj@36baf30c, Main$customObj@7a81197d, Main$customObj@5ca881b5, Main$customObj@24d46ca6]
        
        // 別インスタンスであることを確認
        System.out.println(objList == objList2);
        // → false

        // Listは別インスタンスだが、個々の要素は同じオブジェクトを参照している。
        System.out.println(objList.get(0) == objList2.get(0));  // →true
        System.out.println(objList.get(1) == objList2.get(1));  // →true
        System.out.println(objList.get(2) == objList2.get(2));  // →true
    }
    
    private static class customObj {
        int valInt;
        String valStr;
        
        // Getter,Setter,コンストラクタは省略
    }
}

複製したListは新しい領域が割り当てられているが、参照しているオブジェクトは使い回し。
図にすると以下のような感じ。
Java-Listメモリ割り当て

配列の要素の増減や並べ替えをする場合は、相互に影響はないが、個々の要素の中身を変更する場合は影響が出るので注意が必要。

Profile

管理人プロフィール

都内でITエンジニアをやってます。
変遷:中規模SES→独立系SIer→Webサービス内製開発
使用技術はその時々でバラバラですが、C#、AWSが長いです。
どちらかと言うとバックエンドより開発が多かったです。
顧客との折衝や要件定義、マネジメント(10名弱程度)の経験あり。
最近はJava+SpringBootがメイン。

Recommend