假設我們有一個ArrayList myArray。我想通過調用它的函數來修改一個對象。如果我這樣做,原始對象是否會改變?ArrayList並修改其中包含的對象
myArray.get(0).myModyfyingFunction();
爲了進一步澄清 - 我很擔心,如果get()方法實際上返回到我原來的對象的引用,或者它只能回到我原來的對象的副本。
假設我們有一個ArrayList myArray。我想通過調用它的函數來修改一個對象。如果我這樣做,原始對象是否會改變?ArrayList並修改其中包含的對象
myArray.get(0).myModyfyingFunction();
爲了進一步澄清 - 我很擔心,如果get()方法實際上返回到我原來的對象的引用,或者它只能回到我原來的對象的副本。
get()
將返回一個對象的引用,從來沒有一個副本。對返回的引用做的任何修改都將在對象本身上進行
謝謝,我讀過很多博客,它說Java中的對象總是被價值傳遞,這就是爲什麼我很困惑。 – 2012-03-19 17:27:10
確實如此,所有對象都按值傳遞。令人困惑的部分是,_references_也被值傳遞 - 意味着當你添加一個對象到一個ArrayList時,你最終會得到兩個指向同一個對象的引用,如果你修改了一個引用,那麼「other」也會被修改,因爲兩者都指向相同的對象 – 2012-03-19 17:38:18
@PrimožKralj:「對象」不是Java中的值。對象永遠不會被傳遞或分配。你正在分配和傳遞引用,總是通過值爲 – newacct 2012-03-19 21:58:28
Java永遠不會返回對象的副本,只會複製到對象的引用。因此,該方法肯定會改變索引爲0的對象。
如果方法創建一個對象,您可以獲得對象的「副本」,例如,如果可能,通過使用return object.clone();
,但實際上是返回的是對該方法中仍然創建的副本的引用。因此,您可以從更廣泛的意義上獲得對象的「副本」,但ArrayList#get(...)
不會那樣做 - 並且按照慣例,除非明確聲明,否則getter都不應該這樣做。
謝謝,我的理解現在更好;) – 2012-03-19 17:29:27
它爲您提供對該對象的引用,因此如果您的函數在其狀態中執行任何修改,則您的對象將被修改。
同樣,當你做這種情況:
ArrayList myArray = new ArrayList();
MyObject obj = new MyObject();
myArray.add(obj);
obj.myModifyingFunction();
myArray.get(0).equals(obj); // returns true
myArray.get(0) == obj; // returns true as well
'myArray.get(0).equals(obj);'如果'obj'不是相同的實例,但只在邏輯上相等時,實際上甚至可能返回true(取決於'等於()')。 – Thomas 2012-03-19 17:21:59
好的觀察,我修改了我的答案,以澄清該對象被修改,它是相同的引用,添加一個(也是邏輯上相同)。 – 2012-03-19 17:27:55
謝謝您的解釋並提供示例。 – 2012-03-19 17:28:00
如果您存儲任何對象ArrayList中,對象是不可複製的,並在對象中的任何改變應該在對象本身體現。
例如我們在任何其他類
List<NewClass> newclasses = new ArrayList<NewClass>();
NewClass class1 = new NewClass();
class1.setMystring("before1");
NewClass class2 = new NewClass();
class2.setMystring("before2");
newclasses.add(class1);
newclasses.add(class2);
newclasses.get(0).setMystring("after1");
System.out.println(class1.getMystring());
這將輸出after1的主方法類的NewClass
public class NewClass {
private String mystring="";
/**
* @return the mystring
*/
public String getMystring() {
return mystring;
}
/**
* @param mystring the mystring to set
*/
public void setMystring(String mystring) {
this.mystring = mystring;
}
}
這裏是代碼。
Here is an barebone example. Modify an object of Test class in the List.
public class ModifyArrayList{
public static void main(String [] args){
List<Test> l = new ArrayList<Test>();
Test t1 = gettest();
t1.setStr("John");
t1.setInte(100);
t1.setAno("Smith");
l.add(t1);
t1 = new Test();
t1.setStr("Tracy");
t1.setInte(100);
t1.setAno("Pinto");
l.add(t1);
t1 = new Test();
t1.setStr("Ryan");
t1.setInte(100);
t1.setAno("SmithPinto");
l.add(t1);
t1 = new Test();
t1.setStr("Someone");
t1.setInte(100);
t1.setAno("Else");
l.add(t1);
ListIterator<Test> ti = l.listIterator();
while(ti.hasNext())
{
Test t = ti.next();
if(t.getAno().equals("SmithPinto"))
{
t.setInte(200);
}
//ti.set(t);
ti.remove();
ti.add(t);
}
for (Test t:l)
{
System.out.println("TEST: " + t.getInte());
}
}
}
//Test Class below:
public class Test {
private String str;
private int inte;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public int getInte() {
return inte;
}
public void setInte(int inte) {
this.inte = inte;
}
public String getAno() {
return ano;
}
public void setAno(String ano) {
this.ano = ano;
}
private String ano;
}
for(User user: Users){
user.setName(user.getName() + " New Name");
}
for(User user: Users){
System.out.println(user.getName());
}
你爲什麼不嘗試一下.. :)它的幾行代碼... – PrimosK 2012-03-19 17:15:44
查看這篇文章:http://www.javaranch.com /campfire/StoryPassBy.jsp (在一個杯子概念中的整個貓遠程控制是真棒) – 2012-03-19 17:20:23
好點@PrimosK :)我想我聽到的解釋以及我已經讀過Java是pass-by-只有價值。 – 2012-03-19 17:30:39