1

在测试了代码(见下文)后,我发现我不了解一些基础知识。

A类。

class A {

    private String s;
    private int[] array;
    private B b;

    public A(String s, int[] array, B b) {
        this.s = s;
        this.array = array;
        this.b = b;
    }
}

B类。

class B {

    public int t;

    public B(int t) {
        this.t = t;
    }

}

我认为我之后所做的任何更改A a = new A(s, array, b);都会影响a. a和变量s,array的所有字段不都b引用同一个对象吗?

    String s = "Lorem";
    int array[] = new int[] {
            10, 20, 30
    };
    B b = new B(12);
    A a = new A(s, array, b);
    s = "Dolor";
    array = new int[] {
            23
    };
    b = new B(777); // Initialized with a new value, a.b keeps the old one. Why?
    System.out.println(a);

输出。

String Lorem
Array [10, 20, 30]
B 12

关于这个。

B b2 = new B(89);
B b3 = b2;
System.out.println(b3);
b2 = null;
System.out.println(b3); // b2 initialized with null, b3 keeps the old one. Why?

输出。

89
89

但是,如果我有两个列表,这表明它们都引用同一个对象。

    ArrayList<String> first = new ArrayList<String>();
    first.add("Ipsum");
    ArrayList<String> second = new ArrayList<String>();
    second = first;
    first.add("The Earth");
    System.out.println(second);  

输出。

[Ipsum, The Earth]
4

4 回答 4

4

区别在于assignmentmodify

赋值 ( =) 使变量指向别的东西,所以这不会改变基础数据。因此,指向相同数据的任何其他变量都不会改变。

修改(除了 之外的几乎所有内容=)不会改变变量指向的内容,它只是修改底层对象。因此,指向相同数据的任何其他变量都会发生变化。

以你为例:

b = new B(777);是赋值,所以 onlyb改为指向别的东西。a.b不会改变。

b2 = null;是赋值,所以 onlyb2改为指向别的东西。b3不会改变。

如果您说b2.t = 5,这将是修改(我们没有为 分配新值b2,我们通过更改其成员之一来修改它),因此b3也会发生变化。

我希望能解释它。

于 2013-05-27T07:21:04.303 回答
1

不。问题是,您没有更改 a,而是为 s 分配了一个新值。S 是一个字符串,它是不可变的,这意味着您永远无法更改 s 的值。但是,您可以更改 S 中的引用,这就是您正在执行的操作。

于 2013-05-27T07:20:15.837 回答
1

为了让自己更清楚,请尝试这些代码行..

String s = "Lorem";
int array[] = new int[] {10, 20, 30};
B b = new B(12);
//A a = new A(s, array, b);

s = "Dolor";
array = new int[] {23};
b = new B(777);
A a = new A(s, array, b);
System.out.println(a);


ArrayList<String> first = new ArrayList<String>();
first.add("Ipsum");
ArrayList<String> second = new ArrayList<String>();
second = first;
second.add("The Earth");
first.remove("The Earth");
System.out.println("second :"+second);

在创建类 A 的实例时(在调用类 A 构造函数时),字符串、数组和对象 b 所持有的当前值是什么将被打印出来。创建类 A 实例后,String s、array 和 object b 将被称为 a.array 等。如果为 s、array 和 b 分配一个新值,它不会影响 A 类实例。

对于数组列表问题,两个数组列表将仅引用相同的参考。如果你想要不同的参考,那么就这样做......(但总是 = 分配运算符只会做​​相同的参考)

    ArrayList<String> first = new ArrayList<String>();
    first.add("Ipsum");
    ArrayList<String> second = new ArrayList<String>(first);
    second.add("The Earth");
    System.out.println("first :"+first);        
    System.out.println("second :"+second);     
于 2013-05-27T08:06:01.337 回答
0

感谢 Dukeling 解释分配如何与对象和原语一起工作,我在这里添加以解释列表在对它们执行操作时如何工作。

当我们考虑问题中上述代码中创建的两个数组列表时,变量firstsecond都指向驻留在内存中的同一个数组对象。

因此,当执行添加操作时,底层对象本身就会更新。所以打印操作打印第二个数组列表,它指向在创建第一个数组列表期间创建的相同数组列表对象。

于 2013-05-27T07:50:59.460 回答