Java中的参数传递(ArrayList与整数)

时间:2019-04-24 03:00:30

标签: java arraylist methods parameters

Java严格按值传递。例如,如果我将整数传递给更改其值的方法而没有返回该值,则main方法中的整数将不会更改。

但是,当我将ArrayList传递给将项目添加到列表的方法时,事实证明该方法更改了main方法中的ArrayList。

public class test {
    public static void main(String[] args) {
        // create a array list
        ArrayList<String> item = new ArrayList<String>();
        addItems(item);
        System.out.println("Items in the main method are: ");
        for (int i = 0; i < item.size(); i++) {
            System.out.println(item.get(i));
        }
        System.out.println("\n***************************\n");
        int num = 0;
        plusOne(num);
        System.out.println("The value of num in the main method is: " + num);
    }

    //add two items to arrayList
    public static void addItems(ArrayList<String> item) {
        item.add("Item #1");
        item.add("Item #2");
        System.out.println("Items in the addItems method are: ");
        for (int i = 0; i < item.size(); i++) {
            System.out.println(item.get(i));
        }

    }

    //add one to num
    public static void plusOne(int num) {
        num = num +1;
        System.out.println("The value of num in the plusOne method is: " + num);

    }
}

以下是输出:

Items in the addItems method are: 
Item #1
Item #2
Items in the main method are: 
Item #1
Item #2

***************************

The value of num in the plusOne method is: 1
The value of num in the main method is: 0

这令人困惑。 为什么addItems()更改了itemplusOne()没有更改num呢? 有人可以解释吗?谢谢!

4 个答案:

答案 0 :(得分:1)

您需要区分按值传递和按引用传递。

当您将自己的自定义类的实例或List实例之类的对象作为方法的参数传递时,它们将通过引用传递。基本上,您仍然有一个指向原始对象的指针,并且您正在直接编辑该对象。这就是为什么您在List中看到新项目的原因。

但是,在Java中,原始数据类型和诸如String之类的不可变类是按值传递的。换句话说,您在num方法内收到的plusOne与方法外的num不同。这就是为什么您看不到方法范围之外的更改的原因。

只要看一下String的文档,您就会看到大量的方法吸收String并返回一个新的String。他们不会直接修改输入字符串。

答案 1 :(得分:0)

这只是引用(如果您熟悉C / C ++,则为指针)。

在Java中,列表/数组...或任何对象都有引用,这表示Java将它们存储在同一存储单元中。

因此,当您将对象String传递给函数 addItems ()时,该对象仍保留引用。而且该函数内部对象的任何更改都将受到该变量的影响,因为该变量存储在同一存储单元中。

另一方面, plusOne()原始类型(int / long / double)接收参数,并且没有引用。因此,函数内部的任何更改都不会受到影响。

如果您更改 plusOne(Integer num)而不是(int num),然后将参数íInteger发送给您,

答案 2 :(得分:0)

按值传递-在这种情况下,要传递的值是指向保存数组实例的内存块的地址(Java称这些引用)。

这在您的本地参数item中分配。当您执行item.add(...)时,它将尝试取消引用-查找-本地item中的地址指向的对象-并对其执行操作(add

为说明这仍然是按值传递,请考虑以下因素(语法可能并不完全有效):

ArrayList<String> x = null;
addItems(x);

void addItems(ArrayList<String> arr) {
   // arr will now have the null address
   // arr.add("xxx"); -> throws NullPointerException -> nothing to dereference

   // Consider another scenario, if here I do:
   arr = new ArrayList<>();

   // x outside won't see the change, because it had copied over its address, null
   // but not the "real" x symbol reference itself.
}

对于诸如int之类的图元,其值是内容本身,诸如3的值是复制到本地参数的一系列位。

但是对于非基本体,任何从Object派生的内容-您基本上都将地址作为值-直到应用.运算符为止,该运算符将查找变量引用的对象。

希望更有意义。

答案 3 :(得分:0)

这是非常基本的概念,无论Java是通过引用传递还是通过Value传递?回答Java是按值传递的,在您的情况下,当您传递原始类型时,它是通过该值的副本传递的(所有原始类型都不是引用类型),因此num在main方法中不更改,并且在ArrayList会作为对指向同一内存位置的 addItems()方法的引用的副本传递。

为进一步了解您可以从此链接Is java pass by reference or pass by value引用帖子

enter image description here