Звоните по ссылке или звоните по значению
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