我已经阅读了Jon Skeet的[excellent] article关于在Java中传递值并在同一主题上看到this question的信息。我相信我理解他们但我仍然是 想知道的是回报值。
当一个对象被返回时(来自一个getter),后来改变了它的原始范围(它来自哪里)是该变量所拥有的对象引用,getter的返回值被指派改变?满口的男孩..
借用一个例子:
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。
我原来问题的答案很棒,但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
答案 0 :(得分:6)
它会打印一次Rover。
原因:
public void setName(String name)
{
this.dog = name;
}
public static void main(String args[])
{
Dog myDog = new Dog("Rover");
String dogName = myDog.getName(); // here you are setting dogName to rover
myDog.setName("Max"); // Here you are setting the String field of a Dog object to "Max" (just reassigning the reference and making it point to Max"
System.out.println(dogName); // DogName is still Rover.
// do dogName = myDog.getName(); and print it.. And see what happens :)
}
答案 1 :(得分:3)
是否打印Rover或Max?
它将打印Rover
。
因为,您已经从该Dog
对象中检索了值。稍后更改为Dog
对象myDog
,不会影响变量dogName
当一个对象被返回时(来自一个getter)然后被改变了 它的原始范围(它来自哪里)是对象引用 由赋予getter返回值的变量所拥有 改变?
不,它不会改变您指定的参考。因为您已经检索了该值。
答案 2 :(得分:2)
正如许多答案所述,&#34; Rover&#34;将打印,因为您已更改dog
内的实际字符串。你还没有改变字符串本身(你不能这样做,因为字符串是不可变的,也就是不可改变的。)
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
}
这可能会给人一种印象,即一旦使用getter从另一个对象中检索内部对象,它就完全是独立的,您可以根据需要进行更改。事情并非总是如此。字符串是不可变的,因此您无法更改其内部状态。但是,如果您访问了一个可变的对象(也就是可以更改)并在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)。把对象想象为&#34;没有特别的地方&#34;以及针对这些对象的变量。
这么类比;你(一个Dog
对象)有一个你关心的房屋的地址簿(其他对象)。您可以将地址簿更改为指向其他房屋,其他任何人都不会关心。但是,如果你给一个房子发一封信,说#34;把门涂成绿色的&#34;有房子地址的其他人都会注意到。
一般规则是,如果您更改变量以指向另一个对象,只更改变量(例如更改地址簿中的地址),这总是涉及=
并且可能涉及{{1 (但可能没有,新的用字符串隐藏)。另一方面,如果您在对象上使用方法(例如将包裹发送到您拥有地址的房屋),那么该对象可见的任何地方都会看到更改(这总是涉及方法的new
这是一个setter(或以其他方式更改对象,如.
))
答案 3 :(得分:0)
它将是Rover,因为在Dog对象中,您只是将引用从一个String对象(&#34; Rover&#34;)更改为另一个(&#34; Max&#34;),但dogName仍引用& #34;流动站&#34 ;.顺便说一句,你应该自己运行代码。
答案 4 :(得分:0)
通过这样做:
String dogName = myDog.getName();
您正在创建一个新的String对象,其中包含&#34; Rover&#34;它没有引用对象myDog中的属性dog:它们是完全独立的 因此,当您修改myDog的狗值时,此更改不会影响变量&#34; dogName&#34;