关于Java基础问题。

以下是我的测试代码

public class Test {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "name = " + name;
    }
}
List<Test> tests = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Test test = new Test();
            test.setName("Test" + i);
            tests.add(test);
        }

        Test test = tests.get(15);
        test.setName("new");
        Log.e("Test", test.toString());
        Log.e("Test", tests.get(15).toString());

这是实际的输出:

Test: name = new
Test: name = new

我感觉期待的输出应该是这样的:

Test: name = new
Test: name = Test15

这个差异是为什么啊?我并没有对list中的元素进行过修改,我缺少了哪个知识点导致我无法理解这个问题?

阅读 4.2k
9 个回答
Log.e("Test", test.toString());
Log.e("Test", tests.get(15).toString());

这两句话操作的是同一个引用对象,就是被你修改的那个,如果你想拿出来修改而不改变列表里的元素,需要拷贝一个新的对象出来再做修改。

实现的方式,Test类实现Cloneable接口的clone方法

public class Test implements Cloneable {

    //这里是属性以及get/set方法

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试代码

Test test = tests.get(15).clone;
test.setName("new");
Log.e("Test", test.toString());
Log.e("Test", tests.get(15).toString());

因为变量test指向的内存空间和tests.get(15)指向的内存空间是一致的。你对共同的内存中数据进行修改,所有的引用指向的对象数据都发生了变化。

你想让list中的元素不变,你可以做一个deep copy。

Test test = tests.get(15);
test.setName("new");//你现在的操作其实就是对tests.get(15)的操作,相当于tests.get(15).setName("new");
Log.e("Test", test.toString());
Log.e("Test", tests.get(15).toString());
Test test = tests.get(15);
test.setName("new");

这里不是被你自己改了吗?

Test test = tests.get(15);
test.setName("new");//这里修改了属性,会影响到list里面的对象的
Log.e("Test", test.toString());
Log.e("Test", tests.get(15).toString());
Test test = tests.get(15);
此时的test指向的就是tests.get(15)对象,对test做修改等于对tests.get(15)进行修改。

两个对象的地址是一样的,即两个对象是相同的,所以修改其中一个,另一个也会变得。

你把这句话Test test = tests.get(15);改成Test test = new Test();, 你就可以得到你期待的输出了。 我同意@中传王正一 的解释,就不重复了。

新手上路,请多包涵

其实就是传递的一个引用,你改变了他,他们都是指向一个对象,肯定就是输出这样啊

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题