Передача параметров (ArrayList vs Integer) в Java - PullRequest
0 голосов
/ 24 апреля 2019

Java строго передается по значению.Например, если я передам целое число в метод, который изменяет его значение, и не возвращает его, целое число в основном методе не будет изменено.

Однако, когда я передал ArrayList методу, который добавляет элементы в список, оказалось, что метод изменил ArrayList в методе main.

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() изменилось item, а plusOne() не изменилось num?Может кто-нибудь объяснить это?Спасибо!

Ответы [ 4 ]

1 голос
/ 24 апреля 2019

Необходимо различать передачу по значению и передачу по ссылке.

Когда вы передаете объект, такой как экземпляр вашего собственного пользовательского класса или экземпляр List, в качестве аргумента вашего метода, они передаются по ссылке. По сути, у вас все еще есть указатель, указывающий на исходный объект, и вы редактируете объект напрямую. Вот почему вы видите новые предметы в вашем List.

Однако в Java примитивные типы данных и неизменяемые классы, такие как String, передаются по значению. Другими словами, num, полученный вами внутри вашего plusOne метода, НЕ тот же num, который вы получили за пределами метода. Вот почему вы не увидите свои изменения вне области действия метода.

Достаточно взглянуть на документацию для String , вы увидите, как тонна метода принимает String и возвращает NEW String. Они не будут изменять входную строку напрямую.

0 голосов
/ 24 апреля 2019

Это очень основные понятия, передается ли Java по ссылке или передается по значению?Ответить, что Java передается по значению, и в вашем случае, когда вы передаете примитивный тип, он передается копией этого значения (все примитивные типы не являются ссылочным типом), следовательно, num не изменяется в основном методе и в случаеArrayList передается как копия ссылки на метод addItems () , который указывает на ту же область памяти.

Для дальнейшего понимания вы можете сослаться на пост по этой ссылке Является ли Java передачей по ссылке или передачей по значению

enter image description here

0 голосов
/ 24 апреля 2019

Это передача по значению - в этом случае передаваемое значение является адресом (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 - вы в основном получаете адреса в качестве значения - пока вы не примените оператор ., который ищет объект, на который ссылается переменная.1019 *

Надеюсь, что это имеет больше смысла.

0 голосов
/ 24 апреля 2019

Это просто ссылка (или указатель, если вы знакомы с C / C ++).

В Java список / массив ... или любой объект имеет ссылку, означает, что Java хранит их в той же ячейке памяти.

Поэтому, когда вы передаете объект String в функцию addItems (), ссылка на этот объект сохраняется. И на любое изменение объекта внутри функции будет влиять переменная, поскольку она хранится в той же ячейке памяти.

С другой стороны, plusOne () получают параметр в типе примитива (int / long / double), и он не имеет ссылки. Таким образом, любые изменения внутри функции не будут затронуты.

Если вы измените plusOne (Integer num) вместо (int num) и отправите параметр Integer, вы увидите разницу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...