简体   繁体   English

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

[英]Parameter Passing (ArrayList vs Integer) in Java

Java is Strictly Pass by Value. Java严格按值传递。 For example, if I pass an integer to a method that changes the value of it and don't return the value, the integer in the main method would not be changed. 例如,如果我将整数传递给更改其值的方法而没有返回该值,则main方法中的整数将不会更改。

However, when I passed an ArrayList to a method that adds items to the list, it turned out that the method changed the ArrayList in the main method. 但是,当我将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);

    }
}

Here's the output: 这是输出:

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

This is confusing. 这很混乱。 why addItems() changed item while plusOne() didn't change num ? 为什么addItems()更改了itemplusOne()没有更改num Could someone explain it? 有人可以解释吗? Thank you! 谢谢!

You need to differentiate between pass by value and pass by reference. 您需要区分按值传递和按引用传递。

When you pass an object like an instance of your own custom class or a List instance as an argument to your method, they're passed by reference. 当您将对象(例如您自己的自定义类的实例或List实例)作为方法的参数传递时,它们将通过引用传递。 Basically, you still have a pointer pointing to the original object and you're editing the object directly. 基本上,您仍然有一个指向原始对象的指针,并且您正在直接编辑该对象。 This is why you see new items in your List . 这就是为什么您在List看到新项目的原因。

However, in Java, primitive data types and immutable classes like String are passed by value. 但是,在Java中,原始数据类型和不可变类(如String是通过值传递的。 In other words, the num you received inside your plusOne method is NOT the same num you have outside the method. 换句话说,该num您在里面收到plusOne方法是不一样的num你有方法之外。 This is why you won't see your changes outside the scope of the method. 这就是为什么您看不到方法范围之外的更改的原因。

Just take a look at the documentation for String you'll see a ton of method taking in a String and return a NEW String . 只需看一下String的文档,您就会看到大量使用String并返回一个NEW String They won't modify the input string directly. 他们不会直接修改输入字符串。

This simply the reference (or pointer if you are familiar with C/C++). 这只是引用(如果您熟悉C / C ++,则为指针)。

In Java a List/ Array ... or any object has a reference, mean that Java stores them in the same memory cell. 在Java中,List / Array ...或任何对象都有引用,这意味着Java将它们存储在同一存储单元中。

So when you pass the object String to function addItems (), a reference still keeps for this object. 因此,当您将对象String传递给addItems ()函数时,该对象的引用仍然保留。 And any change for the object inside the function will be affected by the variable because it stores in the same memory cell. 由于变量存储在同一存储单元中,因此该函数内部对象的任何更改都将受到该变量的影响。

In the other hand, plusOne() receive param in primitive type (int/ long/ double), and it does not have a reference. 另一方面, plusOne()接收原始类型 (int / long / double)的参数,并且它没有引用。 So any change inside the function will not be affected. 因此,函数内部的任何更改都不会受到影响。

If you change plusOne(Integer num) instead of (int num) and send the param í Integer, you will see the difference. 如果更改plusOne(Integer num)而不是(int num)并发送参数íInteger,您将看到区别。

It is pass by value -- in this case, the value being passed is an address (Java calls these references) to a block of memory holding the array instance. 它是按值传递的-在这种情况下, 传递的值是保存数组实例的内存块的地址 (Java称为这些引用)。

This gets assigned in your local parameter: item . 这将在您的本地参数: item分配。 When you do item.add(...) , that tries to dereference -- look-up -- the object pointed to by the address in the local item -- and execute the operation ( add ) on it. 当您执行item.add(...) ,它将尝试取消引用-查找-本地item地址指向的对象-并对其执行操作( add )。

To illustrate that this is still pass by value, consider the following (syntax may not be completely valid): 为了说明这仍然是按值传递的,请考虑以下因素(语法可能并不完全有效):

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.
}

In the case of primitives like int , the value is the content itself, a value like 3 is series of bits copied over to the local parameter. 对于像int这样的图元,值是内容本身,像3这样的值是复制到局部参数上的一系列位。

But for non-primitives, anything descending from Object -- you get basically addresses as the value -- until you apply the . 但是对于非基本元素,任何源自Object东西(基本上就是地址)都作为值,直到应用. operator, which look-up the object referenced by the variable. 运算符,它查找变量引用的对象。

Hope that makes more sense. 希望这更有意义。

This is very basic concepts whether Java is pass by reference or pass by Value? 这是Java是通过引用传递还是通过Value传递的非常基本的概念? to Answer that Java is pass by Value and in your case when you are passing primitive type it is being passed by a copy of that value (all primitive types are of not reference type) hence num is not changing in main method and in case of ArrayList it is being passed as a copy of the reference to addItems() method which is pointing to the same memory location. 回答Java是按值传递的,在您的情况下,当您传递原始类型时,它是通过该值的副本传递的(所有原始类型都不是引用类型),因此num在main方法中不更改,并且在ArrayList作为引用的副本传递给addItems()方法,该方法指向相同的内存位置。

For further understanding you can refer post from this link Is java pass by reference or pass by value 为了进一步理解,您可以从此链接引用发布。java是按引用传递还是按值传递

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM