Java:方法似乎是通过引用传递的

时间:2013-05-15 22:12:49

标签: java reference

我始终了解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。

2 个答案:

答案 0 :(得分:4)

Java确实按值传递,但在引用参数的情况下,它是传递的引用的值,而不是对象的值。这会产生副作用,即这些引用指向的实例可以在方法内部更改,并且在方法返回后可以看到更改。

答案 1 :(得分:0)

Java总是按值传递参数。

正如其他人所提到的,为引用类型传递的“值”是指针。该指针指的是指示对象的内存位置。将引用类型作为参数传递时,不能更改在调用代码中传递的指针,但可以在调用的代码中更改指示的引用类型的成员。没有办法解决它。

一种解决方案是制作对象的防御性副本,然后将其引用传递给您的方法。

另一个解决方案是设计代码,尽可能避免引用类型中的副作用,除非这些更改是被调用代码为调用者实现的合同的一部分。