Объясните, каким образом метод Arrays.fill() заполняет двумерный массив в цикле for each

int [][] array = new int[5][5];
                for(int [] ints: array) {
                    Arrays.fill(ints, 3);
                }
                System.out.println(Arrays.deepToString(array));

Вывод:

[[3, 3, 3, 3, 3], [3, 3, 3, 3, 3], [3, 3, 3, 3, 3], [3, 3, 3, 3, 3], [3, 3, 3, 3, 3]]

Объясните, каким образом локальный ints изменяет значения в array.


Ответы (1 шт):

Автор решения: Perfect Voyage

Когда вы пытаетесь выполнить ints = Arrays.copyOf(arr, arr.length) находясь в теле цикла for each, вы меняете не саму ссылку на переменную array, а присваиваете ссылку на новый массив "локальной" ссылке ints.

А дело всё в том, что copyOf возвращает новый объект. Метод fill в свою очередь работает непосредственно с переданным объектом(ссылкой). Посмотреть это можно нажав ctrl + ЛКМ (для IDEA)

public static void fill(int[] a, int val) {
    for (int i = 0, len = a.length; i < len; i++)
        a[i] = val; // ничего не возвращает
}

public static int[] copyOf(int[] original, int newLength) {
    int[] copy = new int[newLength];
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy; // возвращает массив
}

Следующий пример наглядно демонстрирует, что при попытке(в цикле for each) присваивания объекту новой ссылки - ничего не происходит.

   public class Person {
    public String name = "name";

    public static void main(String[] args) {
        Person person = new Person();
        person.name = "1";

        Person[] massive = new Person[]{person};


        for (Person s : massive) {
            s = new Person();
            s.name = "haha!";
            // not change!
        }

        System.out.println(massive[0].name);
        System.out.println(person.name);
    }
    
}
→ Ссылка