Java是否应被视为“严格按值传递”?

时间:2019-07-11 08:17:08

标签: java arrays list pass-by-value

在“按值传递”中,当将参数按值传递给方法时,这意味着将原始变量的副本发送给该方法,而不是原始变量的副本,因此该方法内部应用的任何更改实际上只会影响复制版本而不是原始版本。

例如,

public class Test {



    private void squareNumber(int number){
        number=number*number;
    }

    public static void main(String[] args) {

       int x=2;


        System.out.println(x);  //output    =   2

        new Test().squareNumber(x);

        System.out.println(x);//output    =   2

    }
}

但是对于Arrays和List来说,这是不行的,下面是ArrayList的示例

public class Test {


    private void squareOfList(List<Integer> integerList){
        for (int i=0;i<integerList.size();i++) {
            integerList.set(i,integerList.get(i)*integerList.get(i));

        }
    }


    public static void main(String[] args) {

        List<Integer> nums= new ArrayList<>();
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);


        System.out.println(nums); // output  =  [2, 3, 4, 5]

        new Test().squareOfList(nums);

        System.out.println(nums);  // output  =  [4, 9, 16, 25]

    }

}

由于我们已将nums作为参数传递,因此仅方法内部的值应该更改,但它正在更改原始列表的值。 这个“严格按价值传递”这个术语是否成立?

1 个答案:

答案 0 :(得分:1)

int是原始类型,List是引用类型。根据JLS

  

引用类型由动态创建的对象实现,这些对象可以是类的实例,也可以是数组的实例。可以存在对每个对象的许多引用。

在函数中传递任何引用类型的值时,仅复制引用。现在,两个引用(调用方,被调用方)都指向同一动态分配的内存。如果您在被调用方中更改了该内存(动态分配的内存),它将反映在调用方中。

  

原始类型的变量保存该原始类型的值

int是原始类型,它保存该值。当传递给函数时,它将复制该值,并且没有共享的动态分配内存。因此,您对函数所做的所有更改都保留在函数中。

此示例可能会进一步阐明

public class Test {
    private void squareOfList(List<Integer> integerList){
        integerList = new ArrayList<>(); // Refering to a different dynamically allocated memory
    }

    public static void main(String[] args) {
        List<Integer> nums= new ArrayList<>();
        nums.add(2);
        System.out.println(nums); // output  =  [2]
        new Test().squareOfList(nums);
        System.out.println(nums);  // output  =  [2]
    }

}

有关更多信息,请阅读Java语言规范的第4章。