我始终了解Java按值传递参数。我有一些我似乎无法调试的代码。这是一个简化版本:
private isFinished = false;
private int target, count;
public Example(int target){
this.target = target;
}
public void doProcess(int x){
count += x;
}
public boolean isFinished(){
if(x < target){
return false;
} else {
return true;
}
}
private Example example;
public Test(Example e){
this.example = e;
}
public isFinished(){
return e.isFinished();
}
public void doProcess(){
e.doProcess(3);
}
private Example example;
public Generate(Example e){
this.example = e;
}
public void generate(int num){
for(int y=0; y < num; y++){
Test t = new Test(example);
while(t.isFinished == false){
t.doProcess();
}
}
}
Generate类以Example为参数。它使用此示例并将其传递给“Test”。发生的事情是,当调用Generate.generate()时,第一次迭代正常工作,但在每次迭代时,应该使用作为参数传递的示例进行新的测试。当调用doProcess()时,'example'似乎会被改变,当我想要的是每次使用在创建时传递给Generate的相同Example创建一个新的Test。
答案 0 :(得分:4)
Java确实按值传递,但在引用参数的情况下,它是传递的引用的值,而不是对象的值。这会产生副作用,即这些引用指向的实例可以在方法内部更改,并且在方法返回后可以看到更改。
答案 1 :(得分:0)
Java总是按值传递参数。
正如其他人所提到的,为引用类型传递的“值”是指针。该指针指的是指示对象的内存位置。将引用类型作为参数传递时,不能更改在调用代码中传递的指针,但可以在调用的代码中更改指示的引用类型的成员。没有办法解决它。
一种解决方案是制作对象的防御性副本,然后将其引用传递给您的方法。
另一个解决方案是设计代码,尽可能避免引用类型中的副作用,除非这些更改是被调用代码为调用者实现的合同的一部分。