String abc[]={"abc"};
String def[]={};
def=abc;
def[0]=def[0]+"changed";
System.out.println(abc[0]);
Run Code Online (Sandbox Code Playgroud)
通过更改"def"对象,我的abc对象也会被更改.String []数组旁边有哪些其他java对象具有相似特性的特性?可以解释一下吗?为了防止在我改变def时改变abc,我将不得不做def = abc.clone();
pol*_*nts 13
您将对象可变性/不可变性与复制参考值混淆.
在这些图中,[var/index]是一个引用变量,并且{{an Object}}是一个对象.
String abc[]={"abc"};
String def[]={};
[abc] ------> {{a String[1]}}
[0] --------------> {{a String "abc"}}
[def] ------> {{a String[0]}}
Run Code Online (Sandbox Code Playgroud)
现在,您将def引用变量指向与引用变量相同的对象abc:
def=abc;
[abc] ------> {{a String[1]}}
/ [0] --------------> {{a String "abc"}}
/
[def] ---/ {{a String[0]}}
Run Code Online (Sandbox Code Playgroud)
此时,长度为零的数组未被引用,并且应该是可垃圾收集的.我们可以将讨论范围缩小到长度为1的数组.请注意,a String[]是引用数组.在下一行中,您更改了一个数组指向的长度中唯一的元素.
def[0]=def[0]+"changed";
[abc] ------> {{a String[1]}}
/ [0] ---------\ {{a String "abc"}}
/ \
[def] ---/ \--> {{a String "abcchanged"}}
Run Code Online (Sandbox Code Playgroud)
请注意,{{a String "abc"}}它本身没有变异.[abc]而[def]现在指向同一个{{a String[1]}},这是可变的(例如,你可以让数组的元素,这是引用String的对象,指向任何东西).
为了防止
abc在我改变时改变def,我将不得不这样做def = abc.clone();
实际上,这不太准确.让我们看看如果您clone()对可变类型的引用数组会发生什么StringBuilder.
StringBuilder[] abc = new StringBuilder[] { new StringBuilder("Hello") };
StringBuilder[] def = abc.clone();
def[0].append(" world!");
System.out.println(abc[0]); // prints "Hello world!"
Run Code Online (Sandbox Code Playgroud)
这次我不会为你制作图表,但你可以很容易地在纸上画出来.这里发生的是,即使使用自己的元素(即)clone()创建第二个{{a StringBuilder[1]}}对象def != abc,该元素也指向同一个{{a StringBuilder}}对象(即def[0] == abc[0]).
简而言之:
Integer,String等是不可变的如果您想更深入地了解这些问题,我建议如下:
不可变对象是一旦创建就无法更改的对象.String是一个明显的例子.数组是可变的.如果您想要一个不可变的集合,请使用List:
List<String> abc = Collections.unmodifiableList(
Arrays.asList("abc")
);
Run Code Online (Sandbox Code Playgroud)
可变对象有变异器.mutator是修改对象状态的任何方法.塞特斯是一个明显的例子.典型的不可变对象将如下所示:
public class Person {
private final String firstName;
private final String lastName;
private final Date dateOfBirth;
public Person(String firstName, String lastName, Date dateOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = new Date(dateOfBirth.getTime());
}
public String getFirstName() { return firstName; }
public String getLastname() { return lastName; }
public Date getDateOfBirth() { return new Date(dateOfBirth.getTime()); }
}
Run Code Online (Sandbox Code Playgroud)
一般来说,对于不可变对象,所有成员都是final不可变的.Date是上述问题的一个很好的例子.Date不是一成不变的,许多人(包括我自己)认为这是设计错误.由于它是可变的,你必须进行大量的防御性复制.
| 归档时间: |
|
| 查看次数: |
2666 次 |
| 最近记录: |