我已经阅读了Jon Skeet的[excellent] article关于在Java中传递值的信息,并且在同一主题上看到了this question。我相信我了解他们,但我仍然
想知道返回值。
当一个对象被返回时(如从一个吸气剂中返回),然后在其原始范围(从中获取它)中进行了更改,该对象引用被该获取器的返回值分配给的变量所拥有吗?满口的男孩..
举一个例子:
public class Dog {
String dog ;
public String getName()
{
return this.dog;
}
public Dog(String dog)
{
this.dog = dog;
}
public void setName(String name)
{
this.dog = name;
}
public static void main(String args[])
{
Dog myDog = new Dog("Rover");
String dogName = myDog.getName();
myDog.setName("Max");
System.out.println(dogName);
}
}
是否打印Rover或Max?
更新
是否打印流动站。
我最初的问题的答案很好,但理查德·廷格(Richard Tingle)在下面的评论中添加了很多有用的信息,因此我认为我将为后代提供测试课程。
public class Foo {
private ArrayList<Integer> arrayList;
public Foo() {
arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
}
public ArrayList<Integer> getArrayList() {
return arrayList;
}
public void addToArrayList(int item) {
arrayList.add(item);
}
public static void main(String args[]) {
Foo foo = new Foo();
ArrayList<Integer> arrayList = foo.getArrayList();
ArrayList<Integer> cloneList = (ArrayList<Integer>)foo.getArrayList().clone();
System.out.println(arrayList.contains(4));
System.out.println(cloneList.contains(4));
foo.addToArrayList(4);
System.out.println(arrayList.contains(4));
System.out.println(cloneList.contains(4));
}
输出为
false
,false
,true
,false
最佳答案
如许多答案所述,将打印“ Rover”,因为您已更改了dog
中的实际字符串。您尚未更改String本身(由于String是不可变的,又称为不可更改,因此您无法执行此操作)。
public static void main(String args[])
{
Dog myDog = new Dog("Rover"); //myDog contains STRING1 ("Rover")
String dogName = myDog.getName(); //dogName is set to refer to STRING1 ("Rover")
myDog.setName("Max"); //myDog name set to STRING2 ("Max") (STRING1 unaffected)
System.out.println(dogName); //dogName still refers to STRING1 ("Rover"), "rover" printed
}
更一般的概念
这可能给人的印象是,一旦使用吸气剂从另一个对象检索内部对象,它就完全独立了,您可以根据需要进行更改。并非总是如此。字符串是不可变的,因此您无法更改其内部状态。但是,如果您访问了一个可变的对象(也可以更改),并且在
Dog
对象外部更改了其内部状态,则它仍然会影响Dog
对象的内部状态。我将使用ArrayList
展示此概念public class Dog {
public ArrayList<String> names=new ArrayList<String>();
public ArrayList<String> getNames() {
return names;
}
public void setNames(ArrayList<String> names) {
this.names = names;
}
public static void main(String[] args){
Dog dog=new Dog();
dog.getNames().add("Rover");
ArrayList<String> someArrayList=dog.getNames();
someArrayList.add("Rex");
System.out.println(dog.getNames().contains("Rex")); //prints true. dog's internal state effected from afar
someArrayList=new ArrayList<String>(); //change someArrayList to refer to a whole new ArrayList
someArrayList.add("bad");
System.out.println(dog.getNames().contains("bad")); //prints false, someArrayList now points to a different ArrayList to the one internal to dog
}
}
如您所见,如果您检索到arrayList,然后向其添加对象,这将影响Dog中的ArrayList。如果您检索arrayList并将变量设置为完全不同的ArrayList,则这不会影响Dog中的arrayList(因为它的数组ArrayList不同)。将对象视为“没有特别的地方”,并将变量寻址到这些对象。
如此类推;您(
Dog
对象)有一个您关心的房屋(其他对象)的通讯录。您可以将地址簿更改为指向另一所房子,没有人会在意。但是,如果您在写给房子的信中说“将门漆成绿色”,则其他人对该房子的地址都会注意到。一般规则是,如果您更改变量以使其仅指向更改该变量的对象(例如更改地址簿中的地址),则该变量始终包含
=
且可能包含new
(但可能不包含新的字符串被隐藏)。另一方面,如果您在对象上使用方法(例如,将包裹发送到您有地址的房屋),则该对象可见的任何地方都将看到更改(这始终涉及到方法的.
setter(或以其他方式更改对象,例如add
))关于java - Java返回值,对象引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23383303/