List的add方法添加的是对象的引用,但对String为什么不是

public class ListAddTest {
    public static void main(String[] args) {        
         
         List<String> list = new ArrayList<String>();
         List<String[]> list1 = new ArrayList<String[]>();         
            String str = "";
            String [] strs = new String[1];
            for(int i = 0; i < 3; i++){
                str = "" + i;
                strs[0] = "" + i;
                list.add(str);
                list1.add(strs);
                
            }
            for(int i = 0; i < 3; i++) {
                System.out.println( list.get(i));
            }
            System.out.println();
            for(int i = 0; i < 3; i++) {
                System.out.println( list1.get(i)[0]);
            }
            System.out.println();
            System.out.println(list.get(2)==list1.get(2)[0]);
         }

}

的输出为:

0
1
2

2
2
2

false

String也是引用类型,但是list添加String[]的时候就是对象的引用,而添加String的时候就是对象的拷贝,为什么呢?

==比较的是地址,数组和字符串指向地址不同,所以就是false

你这个测试并不能说明:list添加String[]的时候就是对象的引用,而添加String的时候就是对象的拷贝

不是呀,你看我们完全可以忽略System.out.println(list.get(2)==list1.get(2)[0]);这句单看list1里添加的内容其实和list是一样的,但是list输出的结果是0,1,2但list1输出的都是2,也是就说list添加的是strs[]的引用,所以strs[]变化的时候list1里的内容也会变化,而list添加的按说应该是str的引用啊,那为什么str变化了list里的内容没跟着变呢

不是呀,你看我们完全可以忽略System.out.println(list.get(2)==list1.get(2)[0]);这句单看list1里添加的内容其实和list是一样的,但是list输出的结果是0,1,2但list1输出的都是2,也是就说list添加的是strs[]的引用,所以strs[]变化的时候list1里的内容也会变化,而list添加的按说应该是str的引用啊,那为什么str变化了list里的内容没跟着变呢

因为String类是不可变类,顾名思义就是说类的实例是不可被修改的。实例的信息是在创建的时候提供,并且在整个生命周期中都不可改变。在这段代码中,s原来指向一个String对象,内容是“”,然后我们对s进行了+操作,这时,s不指向原来那个对象了,而指向了另一个String对象,内容为”1!",原来那个对象还存在内存中,只是s这个引用变量不再指向他了。