126 Stimmen

Wie man das Äquivalent von Verweisübergabe für Primitivdatentypen in Java macht

Dieser Java-Code:

public class XYZ {   
    public static void main(){  
        int toyNumber = 5;   
        XYZ temp = new XYZ();  
        temp.spielen(toyNumber);  
        System.out.println("Spielzeugnummer in main " + toyNumber);  
    }

    void spielen(int toyNumber){  
        System.out.println("Spielzeugnummer im Spiel " + toyNumber);   
        toyNumber++;  
        System.out.println("Spielzeugnummer im Spiel nach Inkrementierung " + toyNumber);   
    }   
}  

wird folgendes ausgeben:

Spielzeugnummer im Spiel 5  
Spielzeugnummer im Spiel nach Inkrementierung 6  
Spielzeugnummer in main 5  

In C++ kann ich die toyNumber-Variable als Referenzübergabe übergeben, um Schattenbildung zu vermeiden, d.h. eine Kopie derselben Variable zu erstellen, wie unten gezeigt:

void main(){  
    int toyNumber = 5;  
    spielen(toyNumber);  
    cout << "Spielzeugnummer in main " << toyNumber << endl;  
}

void spielen(int &toyNumber){  
    cout << "Spielzeugnummer im Spiel " << toyNumber << endl;   
    toyNumber++;  
    cout << "Spielzeugnummer im Spiel nach Inkrementierung " << toyNumber << endl;   
} 

und die Ausgabe in C++ wird sein:

Spielzeugnummer im Spiel 5  
Spielzeugnummer im Spiel nach Inkrementierung 6  
Spielzeugnummer in main 6  

Meine Frage ist - Was ist der äquivalente Code in Java, um die gleiche Ausgabe wie der C++-Code zu erhalten, unter der Voraussetzung, dass Java pass-by-value anstelle von pass-by-reference ist?

26 Stimmen

Das scheint für mich nicht wie ein Duplikat - die angeblich duplizierte Frage behandelt, wie Java funktioniert und was die Begriffe bedeuten, was Bildung ist, während diese Frage speziell danach fragt, wie man ein Verhalten erhält, das dem Referenzwertähnelt, etwas, was viele C/C++/D/Ada-Programmierer sich fragen könnten, um praktische Arbeit zu erledigen, ohne sich darum zu kümmern, warum Java alles nach Wert übermittelt.

1 Stimmen

@DarenW Ich stimme vollkommen zu - habe für die Wiedereröffnung gestimmt. Oh, und du hast genug Reputation, um dasselbe zu tun :-)

0 Stimmen

Die Diskussion um Primitivtypen ist eher irreführend, da sich die Frage gleichermaßen auf Referenzwerte bezieht.

3voto

itun Punkte 3261
public static void main(String[] args) {
    int[] toyNumber = new int[] {5};
    NewClass temp = new NewClass();
    temp.play(toyNumber);
    System.out.println("Spielzeugnummer in main " + toyNumber[0]);
}

void play(int[] toyNumber){
    System.out.println("Spielzeugnummer in play " + toyNumber[0]);
    toyNumber[0]++;
    System.out.println("Spielzeugnummer in play nach Inkrement " + toyNumber[0]);
}

0voto

Wir setzen a = 5 in der checkPassByValue-Funktion, aber der Wert von a ändert sich nicht. Ebenso können wir bei der Übergabe einer Person die Daten aktualisieren, auf die die Person zeigt, indem wir Person.setName verwenden. Wenn wir jedoch die Person ändern und sie auf eine neue Person() verweisen lassen, wird diese Aktualisierung nicht in der Hauptfunktion widergespiegelt.

class Person {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;

    public Person(String name) {
        this.name = name;
    }

}

public class PassByValueVsReference {
    public static void main(String[] args) {
        int a = 3;
        Person person = new Person("Foo");
        checkPassByValue(a, person);
        System.out.println(a);
        System.out.println(person.getName());
    }

    public static void checkPassByValue(int number, Person person) {
        number = 5;
        person.setName("Foo-aktualisiert");
        person = new Person("Foo_neue Referenz");
    }
}

//C++-Äquivalent von checkPassByValue(int ,Person *);

0 Stimmen

Nun, in C++ entspricht eine Referenz einem de-referenzierten konstanten Zeiger. Du wirst diesen Zeiger auch nicht ändern.

0 Stimmen

Die C++-Äquivalent wäre checkPassByValue(int number, Person * person). Aber in C++ kann ich immer noch checkPassByValue(int &number, Person & person), checkPassByValue(int number, Person & person) oder checkPassByValue(int number, Person person) machen.

0 Stimmen

Nein, das ist das C-Äquivalent mit ´*person´ als Referenz.

0voto

Sam Ginrich Punkte 449

"Pass-by..." ist in Java und C reserviert. Wenn Sie beabsichtigen, eine Wrapper-Instanz eines als Referenz übergebenen primitiven Typs zu ändern, erfolgt dies durch Reflektion. Beispiel für Integer.

public class WrapperTest
{
    static void mute(Integer a)
    {
        try
        {
            Field fValue = a.getClass().getDeclaredField("value");
            fValue.setAccessible(true);
            fValue.set(a, 6);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] args)
    {
        Integer z = 5;
        mute(z);
        System.out.println(z);
    }

}

Ausgabe ist 6 wie in Ihrem C++ Beispiel. Reflektion ist erforderlich, da das Java-Design die Wrapper-Klassen für primitive Typen als unveränderlich betrachtet. Andernfalls kann jede andere Klasse als Wrapper dienen, auch ein Array wie int[] der Länge 1.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X