Argumente als Referenz und gutes Java Buch



  • Bashar schrieb:

    Gar nicht.

    Ich könnte schwören dass ich so etwas in der Vorlesung hatte. Viele Jahre her.



  • Was hast du denn konkret vor?

    Java ist auch eine Insel scheint ganz gut zu sein. Ist auch kein Anfaengerbuch, sollte also fuer dich das richtige sein. Kannst mal reinlesen. Ist gratis online.



  • gastantwort schrieb:

    In java werden alle argumente by value übergeben

    Buch: Java von kopf bis fuß

    Das gilt AFAIK nur für primitive Datentypen.
    Also int, double, char usw.

    Objekte, auch Datentypen die ein Objekt sind, z.B. String oder Integer werden immer als Referenz übergeben.
    Das gleiche gilt für Arrays, in Java werden die auch als spezielle Objekte behandelt. Das merkt man daran, daß es für Arrays Methoden gibt, die man Nutzen kann.
    Einfach in Eclipse mal ein Array hinschreiben und dann den Punktoperator benutzen, Eclipse listet dann die Methoden auf.



  • Korrektor schrieb:

    Objekte, auch Datentypen die ein Objekt sind, z.B. String oder Integer werden immer als Referenz übergeben.

    Referenzen auf Objekte werden genau wie Primitive per Value übergeben. Wenn irgendwas per Referenz übergeben würde, wäre folgendes möglich:

    void fillString(String value)
    {
        value = "Hallo";
    }
    
    String x;
    fillString(x);
    assert x.equals("Hallo");
    


  • Versuchs mal mit diesem Buch:
    http://www.amazon.de/Objektorientierte-Programmierung-Java-ausführliche-Einsteigerseminar/dp/3826675045/

    Am Anfang versuchen viele Java Einführungen, ein Buch über UML zu ersetzen, so auch der Autor dieses Buches, fast ein Viertel des Buches, also knapp 100 Seiten, kann man aber getrost übergehen aber der Rest ist wirklich OK zum Lernen der ersten Schritte, und um Konfusion zu vermeiden.

    Wenn man höhere Ansprüche hat, dann ist die Einführung vom Herrn Baltes-Götz von der Universität Trier
    http://www.uni-trier.de/fileadmin/urt/doku/java/v60/Java6.pdf
    sehr gut, er geht etwas forscher zur Sache, bleibt aber noch einsteigerfreundlich mit Ausgabetabellen, ausführlichen Installationsanleitungen und vor allem umfangreicher und sogar im Vergleich zu Vorgängerversionen optimiert.
    Das Java ist eine Insel Buch ist auch ganz gut, aber mehr für Fortgeschrittene zum Vertiefen oder Nachschlagen.
    Also wenn man lieber Online lernt, oder gerne Ausdruckt, Baltes Götz, wenn lieber Buch, Niemann und Java von Kopf bis Fuß von der Sierra, aber das Sierra Buch ist schon relativ alt, von 2006 - Eventuell doch ein Risiko eingehen, also Niemann + http://www.amazon.de/Weg-zum-Java-Profi-professionelle-Java-Entwicklung/dp/3898646688/ , weils halt aktueller ist, und das ist auch nicht unwichtig.
    Schau dir auf alle Fälle die Einführung vom Baltes-Götz oben an, eventuell brauchst du ja gar kein Buch.



  • nachtfeuer schrieb:

    Versuchs mal mit diesem Buch:
    http://www.amazon.de/Objektorientierte-Programmierung-Java-ausführliche-Einsteigerseminar/dp/3826675045/

    Am Anfang versuchen viele Java Einführungen, ein Buch über UML zu ersetzen, so auch der Autor dieses Buches, fast ein Viertel des Buches, also knapp 100 Seiten, kann man aber getrost übergehen aber der Rest ist wirklich OK zum Lernen der ersten Schritte, und um Konfusion zu vermeiden.

    Ich finde den Einstieg in UML in einem Java Buch nicht schlecht.

    Denn die Objektorientierte Programmierung habe ich erst gelernt, nachdem ich ein Buch über UML gelesen habe.
    Da hat es dann auf einmal Klick gemacht.
    Bei meinem Javabuch "Java als erste Programmiersprache" war das nicht so, das hat zwar ganz gut erklärt was Objekte sind und wie das mit der Datenkapselung ist, aber wie das ganze eigentlich so richtig harmoniert und zu eiem größeren Ganzen durch OOD zusammengesetzt wird, das habe ich erst in diesem Buch gelernt:
    http://www.amazon.de/UML-umfassende-Handbuch-Galileo-Computing/dp/3836214199/



  • LordJaxom schrieb:

    Korrektor schrieb:

    Objekte, auch Datentypen die ein Objekt sind, z.B. String oder Integer werden immer als Referenz übergeben.

    Referenzen auf Objekte werden genau wie Primitive per Value übergeben. Wenn irgendwas per Referenz übergeben würde, wäre folgendes möglich:

    void fillString(String value)
    {
        value = "Hallo";
    }
    
    String x;
    fillString(x);
    assert x.equals("Hallo");
    

    Okay, aber ich halte dagegen bezüglich der Arrays:

    public class CopybyReference{ 
    	public static void change(int[] a){
    		a[0] = 0;
    		a[1] = 0;
    		a[2] = 7;
    	}
    
        public static void main(String[] args){
    		int[] feld = {0, 1, 2};
    		change(feld);
    		System.out.print("feld = { ");
    		for (int element: feld){
    	    	System.out.print(element + ", ");
    		}
    		System.out.print("}\n");		
    	} 
    }
    


  • Das Beispiel ist nicht analog. Klar, dass man das referenzierte Objekt ändern kann (weil die Referenz ja übergeben wird - wie ist an der Stelle egal). Das gilt für Arrays ja genauso wie für alle anderen Referenztypen. Die Referenz kann man aber nicht ändern, da diese by-value übergeben wird, siehe:

    public static void change(int[] a){
       a = new int[] { 0, 0, 7 };
    }
    
    int[] feld = new int[] { 1, 2, 3 };
    change(feld);
    assert feld[2] == 7;
    


  • LordJaxom schrieb:

    Korrektor schrieb:

    Objekte, auch Datentypen die ein Objekt sind, z.B. String oder Integer werden immer als Referenz übergeben.

    Referenzen auf Objekte werden genau wie Primitive per Value übergeben. Wenn irgendwas per Referenz übergeben würde, wäre folgendes möglich:

    void fillString(String value)
    {
        value = "Hallo";
    }
    
    String x;
    fillString(x);
    assert x.equals("Hallo");
    

    So, ich habe nochmal recherchiert.

    Das Problem ist, daß deine Schlußfolgerung falsch ist.

    Objekte werden in Java immer als Referenz an eine Methode übergeben. Der Grund warum dein Beispiel nicht funktioniert, ist ein völlig anderer und zwar der, daß
    mit value = "Hallo"; ein komplett neuer String erstellt wird, der nun dem lokalen Referenzhalter zugewiesen wird.
    Es ist in Java also nicht wie in C/C++ möglich, bestehende Strings zu verändern, sondern es wird immer ein neuer angelegt und die Variable auf den neuen Eintrag referenziert.

    Siehe auch:
    http://docstore.mik.ua/orelly/java-ent/jnut/ch02_10.htm

    Und die Punkte:

    In Java, primitive types are always handled exclusively by value, and objects and arrays are always handled exclusively by reference.

    und

    Although references are an important part of how Java works, Java programs cannot manipulate references in any way.



  • Oder um es anders zu sagen, vor deiner
    value = "Hallo";

    Zuweisung, zeigt value immer noch auf die gleiche Adresse wie x in der main Methode.

    x wird also nicht bei er Übergabe kopiert.
    Wenn es kopiert werden würde, dann würde value zu Beginn auch auf eine ganz andere Adresse zeigen und der Inhalt trotzdem identisch sein.



  • Siehe auch dieses Codebeispiel:

    public class Test {
    
        static String b;
    
    	public static void change(String s){
            if (b == s){
            	System.out.println("b und s zeigen auf die gleiche Adresse!");
            	s = "hallo";
            }
    
            if (b != s){
            	System.out.println("b und s zeigen nun nicht mehr auf die gleiche Adresse");
            }
    	}
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		b = "Blubber";
    
    		change(b);
    
    	}
    }
    

    Ausgabe:

    b und s zeigen auf die gleiche Adresse!
    b und s zeigen nun nicht mehr auf die gleiche Adresse
    

    Der String wird also by Reference an die Methode übergeben und nicht by Value.
    Würde er by Value übergeben werden, so dürfte die erste Zeile nicht ausgegeben werden.

    Ich lag in meinem ersten Posting also richtig.
    Nur primitive Datentypen werden kopiert, alle anderen werden by Reference übergeben.

    Und warum dein zuvor aufgezeigtes Beispiel kein Beweis für deine Vermutung ist, liegt daran, weil dort etwas ganz anders mit der lokalen variable passiert, wie oben beschrieben.



  • LordJaxom schrieb:

    Das Beispiel ist nicht analog. Klar, dass man das referenzierte Objekt ändern kann (weil die Referenz ja übergeben wird - wie ist an der Stelle egal). Das gilt für Arrays ja genauso wie für alle anderen Referenztypen. Die Referenz kann man aber nicht ändern, da diese by-value übergeben wird, siehe:

    public static void change(int[] a){
       a = new int[] { 0, 0, 7 };
    }
    
    int[] feld = new int[] { 1, 2, 3 };
    change(feld);
    assert feld[2] == 7;
    

    Die Referenz selbst wird by value übergeben, das sehe ich auch so, aber nicht das Objekt, denn das wird per Referenz übergeben.

    Und falls die lokale Referenzvariable nur lesend benutzt wird, zeigt sie immer noch auf das lokale Objekt. Das Objekt wurde also niemals kopiert.



  • Korrektur:

    Und falls die lokale Referenzvariable nur lesend benutzt wird, zeigt sie immer noch auf das ursprüngliche Objekt. Das Objekt wurde also niemals kopiert.



  • Langer Rede kurzer Sinn, wir sind uns einig, dass Referenzen by-value übergeben werden. Ich habe nichts anderes behauptet.



  • LordJaxom schrieb:

    Langer Rede kurzer Sinn, wir sind uns einig, dass Referenzen by-value übergeben werden. Ich habe nichts anderes behauptet.

    Also wir sind uns zwar einig, aber ursprünglich hast du auf meinen Satz:

    Objekte, auch Datentypen die ein Objekt sind, z.B. String oder Integer werden immer als Referenz übergeben.

    folgendermaßen geantwortet:

    Referenzen auf Objekte werden genau wie Primitive per Value übergeben. Wenn irgendwas per Referenz übergeben würde, wäre folgendes möglich:

    Der erste Satz ist noch ok und könnte als Ergänzung durchgehen, aber der zweite ist ein Widerspruch zu meinem Gesagten.
    Denn "irgendwas" schließt auch Objekte mit ein.

    Ich sprach von Objekten, du von Referenzen.

    Fassen wir also zusammen:

    Objekte und Arrays werden immer als copy by Referenz übergeben, genau wie ich sagte.
    Referenzen werden als copy by value übergeben, so wie du sagtest.
    Und primitive Datentypen werden immer als copy by value übergeben.



  • Ich stimme zu, wobei der erste Kernsatz aus dem zweiten hergeleitet werden kann, da Objekte und Arrays in Java ausschließlich als Referenz vorliegen können.



  • LordJaxom schrieb:

    Ich stimme zu, wobei der erste Kernsatz aus dem zweiten hergeleitet werden kann, da Objekte und Arrays in Java ausschließlich als Referenz vorliegen können.

    Genau, das ist hier der Punkt. Objekte werden nicht "per Referenz übergeben". In Java kommen Objekte als Variablen oder Ausdrücke direkt schlicht und einfach nicht vor, es gibt von vornherein nur Referenzen auf Objekte. Das gleiche gilt für Strings und Arrays.

    IMO tut man sich keinen Gefallen, wenn man das als Beispiel für Call-by-reference ansieht.

    Wie Java mit Call-by-reference aussehen könnte, kann man sich in C# anschauen. Da gibt es ebenfalls Referenz- und Werttypen, beide werden standardmäßig by value übergeben, können aber optional by reference übergeben werden:

    void Method(ref Foo o) { o = new Foo(); } // ändert übergebene Referenz
    ...
    Foo o = new Foo();
    Foo o2 = o;
    // o und o2 zeigen auf das gleiche Objekt
    Method(ref o);
    // o und o2 zeigen auf verschiedene Objekte
    

Anmelden zum Antworten