Этот код Java:
public class XYZ {
public static void main(){
int toyNumber = 5;
XYZ temp = new XYZ();
temp.play(toyNumber);
System.out.println("Toy number in main " + toyNumber);
}
void play(int toyNumber){
System.out.println("Toy number in play " + toyNumber);
toyNumber++;
System.out.println("Toy number in play after increement " + toyNumber);
}
}
выведет это:
Номер игрушки в игре 5 Номер игрушки в игре после прибавления 6 Номер игрушки в главном 5
В C ++ я могу передать toyNumber
переменную как переданную по ссылке, чтобы избежать затенения, т.е. создать копию той же переменной, что и ниже:
void main(){
int toyNumber = 5;
play(toyNumber);
cout << "Toy number in main " << toyNumber << endl;
}
void play(int &toyNumber){
cout << "Toy number in play " << toyNumber << endl;
toyNumber++;
cout << "Toy number in play after increement " << toyNumber << endl;
}
и вывод C ++ будет таким:
Номер игрушки в игре 5 Номер игрушки в игре после прибавления 6 Номер игрушки в главной 6
Мой вопрос: каков эквивалентный код в Java, чтобы получить тот же результат, что и код C ++, учитывая, что Java передается по значению, а не по ссылке ?
java
pass-by-reference
Ученик
источник
источник
toyNumber
переменная, объявленная вmain
методе, не входит в область видимостиplay
метода. Затенение в C ++ и Java происходит только при вложении областей видимости. См. En.wikipedia.org/wiki/Variable_shadowing .Ответы:
У вас есть несколько вариантов. Тот, который имеет наибольший смысл, на самом деле зависит от того, что вы пытаетесь сделать.
Вариант 1: сделать toyNumber общедоступной переменной-членом класса
затем передайте ссылку на MyToy вашему методу.
Вариант 2: вернуть значение вместо передачи по ссылке
Этот выбор требует небольшого изменения в callsite в главном , так что он читает,
toyNumber = temp.play(toyNumber);
.Вариант 3: сделать класс или статическую переменную
Если две функции являются методами одного класса или экземпляра класса, вы можете преобразовать toyNumber в переменную-член класса.
Вариант 4: создайте массив из одного элемента типа int и передайте его
Это считается хакерским приемом, но иногда используется для возврата значений из встроенных вызовов классов.
источник
toyNumber = temp.play(toyNumber);
чтобы он работал должным образом .Java не вызывается по ссылке, это только по значению
Но все переменные объектного типа на самом деле являются указателями.
Итак, если вы используете изменяемый объект, вы увидите желаемое поведение
Вывод этого кода:
Вы также можете увидеть это поведение в стандартных библиотеках. Например, Collections.sort (); Collections.shuffle (); Эти методы не возвращают новый список, но изменяют его объект аргумента.
Вывод этого кода:
источник
play
; напрmutableList[0] = mutableList[0] + 1;
. Как предполагает Эрнест Фридман-Хилл.private static void play(StringBuilder toyNumber)
- как вы его называете, если это, например, public static int, который возвращает целое число? Потому что у меня есть метод, который возвращает число, но если я его где-то не назову, он не используется.Делать
затем передайте ссылку на его экземпляр. Обратите внимание, что лучше избегать метода, который изменяет состояние с помощью своих аргументов, особенно в параллельном коде.
источник
В Java нельзя передавать примитивы по ссылке. Все переменные объектного типа, конечно, на самом деле являются указателями, но мы называем их «ссылками», и они также всегда передаются по значению.
В ситуации, когда вам действительно нужно передать примитив по ссылке, люди иногда будут объявлять параметр как массив примитивного типа, а затем передавать одноэлементный массив в качестве аргумента. Таким образом, вы передаете ссылку на int [1] и в методе можете изменять содержимое массива.
источник
Для быстрого решения вы можете использовать AtomicInteger или любую из атомарных переменных, которые позволят вам изменить значение внутри метода с помощью встроенных методов. Вот пример кода:
Вывод:
источник
источник