Ten kod 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);
}
}
wyświetli to:
Numer zabawki w grze 5 Numer zabawki w grze po zwiększeniu 6 Numer zabawki w głównym 5
W C ++ mogę przekazać toyNumber
zmienną jako przekaz przez odniesienie, aby uniknąć cieniowania, tj. Tworzenia kopii tej samej zmiennej, co 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;
}
a wynik C ++ będzie taki:
Numer zabawki w grze 5 Numer zabawki w grze po zwiększeniu 6 Numer zabawki w głównym 6
Moje pytanie brzmi: Jaki jest równoważny kod w Javie, który daje takie same dane wyjściowe jak kod C ++, biorąc pod uwagę, że Java jest przekazywana przez wartość, a nie przez odniesienie ?
java
pass-by-reference
Student
źródło
źródło
toyNumber
zmienna zadeklarowana wmain
metodzie nie znajduje się w zakresie wplay
metodzie. Cieniowanie w C ++ i Javie ma miejsce tylko wtedy, gdy występuje zagnieżdżenie zakresów. Zobacz en.wikipedia.org/wiki/Variable_shadowing .Odpowiedzi:
Masz kilka możliwości. Ten, który ma największy sens, zależy tak naprawdę od tego, co próbujesz zrobić.
Wybór 1: uczyń toyNumber publiczną zmienną składową w klasie
następnie przekaż odwołanie do MyToy do swojej metody.
Wybór 2: zwraca wartość zamiast przekazywania przez odwołanie
Wybór ten będzie wymagać małej zmiany w callsite w głównej tak, że czyta,
toyNumber = temp.play(toyNumber);
.Wybór 3: uczyń z niej zmienną klasową lub statyczną
Jeśli te dwie funkcje są metodami tej samej klasy lub instancji klasy, można przekonwertować toyNumber na zmienną składową klasy.
Wybór 4: Utwórz pojedynczą tablicę elementów typu int i przekaż ją
Jest to uważane za włamanie, ale czasami jest wykorzystywane do zwracania wartości z wywołań klas wbudowanych.
źródło
toyNumber = temp.play(toyNumber);
działała zgodnie z oczekiwaniami, musi zostać zmieniona na adres.Java nie jest wywoływana przez odniesienie , jest wywoływana tylko przez wartość
Ale wszystkie zmienne typu obiektowego są w rzeczywistości wskaźnikami.
Więc jeśli używasz mutowalnego obiektu, zobaczysz pożądane zachowanie
Wyjście tego kodu:
Możesz zobaczyć to zachowanie również w bibliotekach standardowych. Na przykład Kolekcje.sort (); Collections.shuffle (); Te metody nie zwracają nowej listy, ale modyfikują jej obiekt argumentu.
Wyjście tego kodu:
źródło
play
; npmutableList[0] = mutableList[0] + 1;
. Jak sugeruje Ernest Friedman-Hill.private static void play(StringBuilder toyNumber)
- jak to nazwać, jeśli jest to na przykład publiczny statyczny int, który zwraca liczbę całkowitą? Ponieważ mam metodę, która zwraca liczbę, ale jeśli gdzieś jej nie wywołam, nie jest używana.Zrobić
następnie przekaż referencję do jej instancji. Zauważ, że najlepiej unikać metody, która mutuje stan poprzez swoje argumenty, szczególnie w kodzie równoległym.
źródło
W Javie nie można przekazywać prymitywów przez odwołanie. Wszystkie zmienne typu obiektowego są oczywiście wskaźnikami, ale nazywamy je „referencjami” i zawsze są one również przekazywane przez wartość.
W sytuacji, gdy naprawdę potrzebujesz przekazać prymityw przez referencję, czasami ludzie będą zadeklarować parametr jako tablicę typu pierwotnego, a następnie przekazać jako argument tablicę jednoelementową. Więc przekazujesz referencję int [1], a w metodzie możesz zmienić zawartość tablicy.
źródło
Aby szybko rozwiązać problem, możesz użyć AtomicInteger lub dowolnej zmiennej atomowej, która pozwoli ci zmienić wartość wewnątrz metody za pomocą wbudowanych metod. Oto przykładowy kod:
Wynik:
źródło
źródło