为什么新对象保留旧对象的属性?



我创建了一个方法,可以对人们施放衰老魔咒,并将他们的年龄减少两倍:

public class Wizard {
void agingSpell (Person x) {
x = new Person(x.age);
x.age -=2;
}
}

以下是描述这些人的类:

public class Person {
int age;
int weight = 90;
String name = Max;
Person (int x){
this.age = x;
}
}

我创建了一个人员和向导实例:

Person max = new Person(26);
Wizard albus = new Wizard();

然后,我将方法称为agingSpell和 sourcemax作为其参数:

albus.agingSpell(Person max);

然后,正如我所看到的,max中的参考值被分配给方法中的x

Person x = max;

现在我们又多了一个对创建对象的引用。接下来,创建一个新对象并保存在x中(再次,我可能是错的(:

x = new Person(x.age)

我理解旧对象要被新对象替换,因此方法中必须没有旧对象的痕迹。但是,如果我编译代码,新对象的年龄也将是 26 .此外,我可以轻松访问旧对象的所有其他字段(当我们将其x引用分配给另一个对象时,它应该是无法访问的(。 我知道我肯定错过了什么。你能帮我弄清楚吗?

这是代码的执行部分:

public class Wizard {
}
public static void main (String [] args){
Wizard albus = new Wizard();
Person max = new Person(26);
albus.agingSpell(max);
System.out.println(max.age);
}

}

你在拼写方法中重新分配x,所以它指向人,然后你改变这个新人的年龄,然后你把那个人扔掉。所以最终结果是没有任何变化。这与执行此操作相同:

void agingSpell(Person p) {
Person throwaway = new Person(p.age);
throwaway.age -= 2;
// when this method returns, "throwaway" literally gets thrown away.
}

一个更好的问题是"如果目的是减少一个人的年龄,你为什么要产生一个新人?让咒语直接更新你传入的人:

class Wizard {
final int DEFAULT_AGE_DECREASE = 2;
...
void agingSpell(Person p) {
this.agePerson(p, DEFAULT_AGE_DECREASE);
}
void agingSpell(Person p, int years) {
// let's keep a person's age a protected field
p.setAge(p.age - years);
// and you'll probably need logic for age hitting/dropping below zero
}
...
}

按如下方式定义agingSpell

void agingSpell(Person x) {
x.age -= 2;
}

-或-

返回正在创建的新对象。请注意,您在agingSpell中创建的新对象的作用域仅限于此方法,即一旦控件出现此函数,新对象将不复存在。

class Wizard {
Person agingSpell(Person x) {
x = new Person(x.age);
x.age -= 2;
return x;
}
}
class Person {
int age;
int weight = 90;
String name;
Person(int x) {
this.age = x;
}
}
public class Main {
public static void main(String[] args) {
Wizard albus = new Wizard();
Person max = new Person(26);
System.out.println(albus.agingSpell(max).age);
}
}

最新更新