为什么我的方法会更改原始变量的值?

时间:2017-06-19 23:53:11

标签: java android variables

我创建了一个将List作为输入brewMethod.getmMethodBrewPours()的方法,并且根据用户的偏好,该方法按原样返回这些变量或乘以数字。我将返回的值存储为新变量brewPours。问题是,这个方法不仅要返回要存储的新值,还要更改原始变量的值。为什么要改变它,我应该怎么做才能防止它?

调用方法的代码:

// Custom class storing sets of data
        brewMethod = i.getParcelableExtra("brew_method");

        //logs original packaged values
        for (int j = 0; j < brewMethod.getmMethodBrewPours().size(); j++) {
            Log.v("Original pour value #: " + j + ": ", brewMethod.getmMethodBrewPours() .get(j).toString());
        }

        //changes values based on users preference
        brewPours = replacePours(brewMethod.getmMethodBrewPours());

        //report the values again of the original packed values, but they are changed for some reason
        for (int k = 0; k < brewMethod.getmMethodBrewPours().size(); k++) {
            Log.v("New value on Original pour value #: " + k + ": ", brewMethod.getmMethodBrewPours() .get(k).toString());
        }

        //log the values of the new variable brewPours
        for (int l = 0; l < brewPours.size(); l++) {
            Log.v("Value for new variable brewPours pour # " + l + ": ", brewPours.get(l).toString());
        }

方法代码:

    public List<Integer> replacePours(List<Integer> waterPours) {

    SharedPreferences pref = getSharedPreferences("preferences", MODE_PRIVATE);

    Integer newServingSize = pref.getInt("pref_key_serving_size", 1);

    if (newServingSize == 2) {
        for (int i = 0; i < waterPours.size(); i++) {
            newPour = waterPours.get(i) * 2;
            waterPours.set(i, newPour);
        }
    }

    return waterPours;
}

输出:

06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 0:: 60
06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 1:: 200
06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 2:: 300
06-19 16:50:34.474 30159-30159/com.brewguide.android.coffeebrewguide V/Original pour value #: 3:: 380
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 0:: 120
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 1:: 400
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 2:: 600
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/New value on Original pour value #: 3:: 760
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 0:: 120
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 1:: 400
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 2:: 600
06-19 16:50:34.475 30159-30159/com.brewguide.android.coffeebrewguide V/Value for new variable brewPours pour # 3:: 760

编辑: 我按照@Vampire的建议调整了方法的代码,得到了我想要的结果。以下是我调整后的代码,谢谢!

public List<Integer> replacePours(List<Integer> waterPours) {

    List<Integer> returnedPours = new ArrayList<>();
    SharedPreferences pref = getSharedPreferences("preferences", MODE_PRIVATE);

    Integer newServingSize = pref.getInt("pref_key_serving_size", 1);

    if (newServingSize == 2) {
        for (int i = 0; i < waterPours.size(); i++) {
            int newPour = waterPours.get(i) * 2;
            returnedPours.add(newPour);
        }
    }
    return returnedPours;
}

2 个答案:

答案 0 :(得分:3)

原始列表已修改,因为修改它。 Java是按值调用的,但是您为方法赋予的值是对对象的引用,而不是对象。这意味着您没有将列表提供给方法并获取列表,但是您将方法的列表引用。在修改引用的对象时,可以修改原始对象。您必须在方法中创建一个新列表并返回该列表,而不是修改您为其提供的列表。

答案 1 :(得分:1)

了解Call-by-reference和call-by-value之间的区别。

在JAVA中,当您在函数中传递对象时,它会传递对该函数的引用。因此,函数中对象的任何更改都会反映函数外部的更改。

在您的情况下,您将通过以下行更改原始对象的值:waterPours.set(i, newPour);

因此,如果您在函数中创建新对象并对其进行修改,那就更好了。

public List<Integer> replacePours(List<Integer> waterPours) {

    List<Integer> tempList = new ArrayList<Integer>(waterPours);

    SharedPreferences pref = getSharedPreferences("preferences", MODE_PRIVATE);

    Integer newServingSize = pref.getInt("pref_key_serving_size", 1);

    if (newServingSize == 2) {
        for (int i = 0; i < tempList.size(); i++) {
            int newPour = tempList.get(i) * 2;
            tempList.set(i, newPour);
        }
    }

    return tempList;
}