Jak zrobić odpowiednik pass by reference dla primitives w Javie
Ten kod Javy:
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);
}
}
Wyświetli to:
Toy number in play 5 Toy number in play after increement 6 Toy number in main 5
W C++ mogę przekazać zmienną toyNumber
jako pass by reference, aby uniknąć cieniowania tj. tworzenia kopii tej samej zmiennej jak poniżej:
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;
}
I wyjście C++ będzie takie:
Toy number in play 5 Toy number in play after increement 6 Toy number in main 6
Moje pytanie brzmi-jaki jest równoważny kod w Javie, aby uzyskać taki sam wynik jak kod C++, biorąc pod uwagę, że Java jest pass by value, a nie pass by reference ?
6 answers
Masz kilka możliwości. Ten, który ma największy sens, zależy od tego, co próbujesz zrobić.
Wybór 1: make toynumber Public member variable in a class
class MyToy {
public int toyNumber;
}
Następnie podaj odniesienie do MyToy do swojej metody.
void play(MyToy toy){
System.out.println("Toy number in play " + toy.toyNumber);
toy.toyNumber++;
System.out.println("Toy number in play after increement " + toy.toyNumber);
}
Wybór 2: Zwraca wartość zamiast pass by reference
int play(int toyNumber){
System.out.println("Toy number in play " + toyNumber);
toyNumber++;
System.out.println("Toy number in play after increement " + toyNumber);
return toyNumber
}
Ten wybór wymagałby małej zmiany miejsca wywołania w main tak, aby brzmiało, toyNumber = temp.play(toyNumber);
.
Wybór 3: uczyń to klasą lub zmienna statyczna
Jeśli obie funkcje są metodami tej samej klasy lub instancji klasy, można przekonwertować toyNumber na zmienną klasy.
Wybór 4: Utwórz tablicę pojedynczych elementów typu int i przekaż
Jest to uważane za hack, ale czasami jest używane do zwracania wartości z inline class invocations.
void play(int [] toyNumber){
System.out.println("Toy number in play " + toyNumber[0]);
toyNumber[0]++;
System.out.println("Toy number in play after increement " + toyNumber[0]);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-24 16:52:35
Java nie jest wywołaniem przez referencję jest to wywołanie tylko przez wartość
Ale wszystkie zmienne typu object są w rzeczywistości wskaźnikami.
Więc jeśli użyjesz Mutowalnego obiektu, zobaczysz zachowanie, które chcesz
public class XYZ {
public static void main(String[] arg) {
StringBuilder toyNumber = new StringBuilder("5");
play(toyNumber);
System.out.println("Toy number in main " + toyNumber);
}
private static void play(StringBuilder toyNumber) {
System.out.println("Toy number in play " + toyNumber);
toyNumber.append(" + 1");
System.out.println("Toy number in play after increement " + toyNumber);
}
}
Wyjście tego kodu:
run:
Toy number in play 5
Toy number in play after increement 5 + 1
Toy number in main 5 + 1
BUILD SUCCESSFUL (total time: 0 seconds)
To zachowanie można zobaczyć również w bibliotekach standardowych. Na przykład Kolekcje.sort (); Kolekcje.shuffle(); Metody te nie zwracają nowej listy, lecz modyfikują obiekt argumentu.
List<Integer> mutableList = new ArrayList<Integer>();
mutableList.add(1);
mutableList.add(2);
mutableList.add(3);
mutableList.add(4);
mutableList.add(5);
System.out.println(mutableList);
Collections.shuffle(mutableList);
System.out.println(mutableList);
Collections.sort(mutableList);
System.out.println(mutableList);
Wyjście ten kod:
run:
[1, 2, 3, 4, 5]
[3, 4, 1, 5, 2]
[1, 2, 3, 4, 5]
BUILD SUCCESSFUL (total time: 0 seconds)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-17 21:24:30
Make A
class PassMeByRef { public int theValue; }
Następnie podaj odniesienie do jego instancji. Zauważ, że metoda, która mutuje stan poprzez swoje argumenty, jest najlepiej unikać, zwłaszcza w kodzie równoległym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-11 09:55:29
W Javie nie można przekazać prymitywów przez odniesienie. Wszystkie zmienne typu object są oczywiście wskaźnikami, ale nazywamy je "referencjami", a także zawsze są przekazywane przez wartość.
W sytuacji, gdy naprawdę musisz przekazać wartość primitive by, ludzie czasami będą deklarować parametr jako tablicę typu primitive, a następnie przekazywać tablicę jednoelementową jako argument. Więc przekazujesz referencję int [1], a w metodzie możesz zmienić zawartość / align = "left" /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-10 20:44:50
Dla szybkiego rozwiązania, możesz użyć AtomicInteger lub dowolnej ze zmiennych atomowych, które pozwolą Ci zmienić wartość wewnątrz metody za pomocą wbudowanych metod. Oto przykładowy kod:
import java.util.concurrent.atomic.AtomicInteger;
public class PrimitivePassByReferenceSample {
/**
* @param args
*/
public static void main(String[] args) {
AtomicInteger myNumber = new AtomicInteger(0);
System.out.println("MyNumber before method Call:" + myNumber.get());
PrimitivePassByReferenceSample temp = new PrimitivePassByReferenceSample() ;
temp.changeMyNumber(myNumber);
System.out.println("MyNumber After method Call:" + myNumber.get());
}
void changeMyNumber(AtomicInteger myNumber) {
myNumber.getAndSet(100);
}
}
Wyjście:
MyNumber before method Call:0
MyNumber After method Call:100
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-15 16:39:57
public static void main(String[] args) {
int[] toyNumber = new int[] {5};
NewClass temp = new NewClass();
temp.play(toyNumber);
System.out.println("Toy number in main " + toyNumber[0]);
}
void play(int[] toyNumber){
System.out.println("Toy number in play " + toyNumber[0]);
toyNumber[0]++;
System.out.println("Toy number in play after increement " + toyNumber[0]);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-10 20:50:14