Звоните по ссылке или звоните по значению

class Box {
    int size;

    Box(int s) {
        size = s;
    }
}

public class Laser {
    public static void main(String[] args) {
        Box b1 = new Box(5);
        Box[] ba = go(b1, new Box(6));
        ba[0] = b1;
        for (Box b : ba)
            System.out.print(b.size + " ");
    }

    static Box[] go(Box b1, Box b2) {
        b1.size = 4;
        Box[] ma = { b2, b1 };
        return ma;
    }
}

What the result? 
A. 4 4 
B. 5 4 
C. 6 4 
D. 4 5 
E. 5 5 
F. Compilation fails 

Ответ А

Я с трудом пытаюсь понять результаты этого кода. Кто-нибудь может мне объяснить результаты?

4 ответа

Решение

Вот некоторые объяснения -

1. Прежде всего, вы должны создать Box в основном () классе -

 Box b1 = new Box(5);  

2. Затем отправьте b1 в метод go() -

   Box[] ba = go(b1, new Bo(6));

Сейчас b1.size это 5

3. В методе go() вы устанавливаете b1.size до 4 с помощью оператора присваивания -

b1.size = 4;  

4. Теперь вы создаете новый Box массив ma -

Box[] ma = { b2, b1 };  

В этом массиве первый элемент b2 и b2.size 6. Смотри пункт 2.

5. Затем вы вернетесь ma и в точке 2 возвращаемый массив ma назначается с ba, Теперь первый элемент массива равен 6, а второй элемент массива равен 4.

6. ba[0] = b1; - это утверждение устанавливает первый элемент ba[0] в b1, Обратите внимание на пункт 2 b1.size был установлен на 4.

Сейчас ba[0].size это 4
а также ba[1].size это 4

И вот почему на выходе 4 4

В Java это всегда передается по значению

Примитивы всегда передаются по значению

Объекты передаются по их ссылкам, и эти ссылки также передаются по значению.

    public static void main(String[] args) {
        Box b1 = new Box(5); //Line1
        Box[] ba = go(b1, new Box(6)); //Line2
        ba[0] = b1; //Line3
        for (Box b : ba)
            System.out.print(b.size + " ");
    }

Ответ (4 4), потому что,

  • В строке 1 вы инициализируете size из Box до 5 внутри конструктора.
  • В строке 2 вы отправляете два объекта в качестве аргументов методаgo(), size объекта, на который ссылается b1, теперь 5, а new Box(6);размер объекта равен 6. Внутри метода вы меняете значение первого параметра с 5 на 4. И, наконец, вы вернули массив ma с b2в качестве первого элемента и b1 как второй элемент. b2 имеет значение 6 и b1 имеет 4.
  • Теперь в строке 3 вы снова меняете значение первого элемента внутри массива. Вы заменили первый элемент внутри массива b2 который имеет значение 6 с b1 чье значение сейчас 4.

Когда Box[ ] ba = go (b1, new Bo(6)); это бег, go конкретизирует ba со следующим массивом: [b2,b1], где b2 имеет размер 6 и b1 имеет размер 4. Чтобы было ясно, go устанавливает размер b1 от 5 до 4. Когда b1, передается go, передается по ссылке, что означает любые изменения b1 внутри go также внесены изменения в b1 объект, который был создан в первой строке main,

Затем запускается следующий код:

ba[0] = b1;

Здесь вы устанавливаете b2 из массива (так как ba[0] относится к b2) равно b1, Теперь оба b2 а также b1 обратитесь к коробке размером 4.

PS Интересный факт, объекты никогда не совпадают напрямую с данными; Объекты - это только адреса, которые соответствуют или ссылаются на данные, записанные в другом месте стека. Так что, технически, когда ba[0] = b1; это бег, b2 просто ссылаясь на те же данные, которые b1 имеет в виду.

В Java все типы примитивов передаются по значению, а остальные, как объекты или массивы, передаются по ссылке. Это означает, что когда вы вызываете метод

go(Box b1, Box b2)

он везде меняет значение b1.size, потому что устанавливает b1.size = 4, поэтому получается A: 4 4

Другие вопросы по тегам