Array wird verändert ohne Rückgabe?

HelloJava

Mitglied
Hallo,
obwohl ich schon lange mit Java gearbeitet habe, ist mir erst jetzt etwas aufgefallen, was ich zuvor nicht für möglich gehalten habe. Das Beispiel ist wie folgt:

Java:
public class ArrayMod{
	
	
	public static void main(String[] args){
		
		int[] array = {1,2,3};
		
		umsortieren( array );
		
		for(int i=0 ; i<array.length ; i++)
		System.out.print(array[i]);
	}
	
	public static void umsortieren(int[] a){
		
		int t = a[1];
		a[1] = a[2];
		a[2] = t;
	}
}

Das Array hat zuerst die Reihenfolge 1,2,3. Danach wird es der Methode umsortieren übergeben, welche zwei Zahlen im Array einfach austauscht. Nun ist es aber so, dass die Methode "umsortieren" das veränderte Array nicht wieder returnt. Wenn ich das Array nach der umsortieren-Methode in der main-Methode wieder ausgebe, ist die Reihenfolge 1,3,2.
Wie ist das möglich? Das Array "array" befindet sich doch in der main-Methode und ist nicht außerhalb als global festgelegt und trotzdem wird es verändert zurückgegeben? Habe ich etwas Grundlegendes missverstanden?

Und warum funktioniert es nicht mit einfachen Zahlen, wie im folgenden Beispiel:

Java:
public class ZahlMod{
	
	
	public static void main(String[] args){
		
		int zahl = 1;
		
		veraendern(zahl);
		
		System.out.print(zahl);
	}
	
	public static void veraendern(int z){
		
		z = 2;
		
	}
}

Hier wird wieder der richtige Wert "1" ausgegeben, wie ich es eigentlich auch beim Array erwartet hätte.
 
Zuletzt bearbeitet:
Und warum funktioniert es nicht mit einfachen Zahlen ..

Du hast die Antwort bereits selbst gegeben. Einfach Datentypen werden nicht manipuliert sondern du arbeitest auf einer Kopie mit identischem Inhalt. Da ein Array und alle von Object abgeleitete Typen aber kein einfachen Datentypen sind, kannst du diese als Parameter übergeben und auch die Daten in der Methode manipulieren.
 
Objekte werden in Java immer als Referenz übergeben. Auch Variablen speichern immer eine Referenz auf das Objekt. Bei primitiven Datentypen dagegen werden niemals Referenzen verwendet, da wird der Wert kopiert.
Es heisst in der JLS (Java language specification) zwar, dass Java grundsätzlich immer "pass by value" verwendet und nicht "pass by reference", jedoch handelt es sich bei den Werten in Java meistens um Referenzen.
 
Zuletzt bearbeitet:
Hey!

Wie die Leute vor mir schon gesagt haben liegt es daran was Array für eine Art von Variable ist oder welchen Datentyp es hat.
Es gibt nämlich grob 2 Arten in Java:

1#: Primitive Datentypen
Beispiele: byte, int, short,long, double, char, float usw.

Diese Werte werden abgespeichert an einer Bestimmten Adresse im Speicher.
Wenn du jetzt diese Werte übergibst wird nicht die Adresse sondern der Wert der Variable übergeben.

Das nennt sich call by value.
Der Wert der alten Variable wird sich also nicht verändern, weil nicht mit der Adresse gearbeitet wird wo etwas gespeichert wird.



2#: Objekte & Arrays
Beispiele: int[], String[], Date, JPanel, Object

So bei dieser Art von Datentypen wird nicht mit dem Wert gearbeitet. Es wird die Adresse (Referenz übergeben)
D.h jedes Programmteil arbeitet mit dem selben Objekt wenn du ihm die Referenz gibst.

Stells dir einfach so vor:

Du hast ein Haus und möchtest das jemand für dich dieses Haus renoviert.
Dein Haus ist jetzt ein Objekt. Dieses Objekt hat eine Adresse (Die Schwammerlgasse 17)

Du gehst zu einer Firma die für renovierungen durchzieht.
Du sagst dieser Firma was du brauchst und gibst Ihnen die Adresse.

(D.h Ihre Fähigkeit Häuser zu renovieren ist eine Funktion, die Adresse die Referenz; Das Objekt)
Nun werden sie das Haus renovieren.
Nach Abschluss der Renovierung gehen sie dann einfach (Wir gehen davon aus das du im vorraus gezahlt hast).

Weißt du was ich damit meine?
Sie geben dir das Haus nicht wieder zurück 😛


lg

rene
 
Vielen Dank euch allen und inbesondere an Vancold für das schöne Beispiel!

Nun habe ich aber noch eine Frage. Was passiert, wenn ich das ursprüngliche Array bzw. die Reihenfolge wieder brauche? Kann man es irgendwie davor schützen verändert zu werden?


Java:
public class ArrayMod{
    
    
    public static void main(String[] args){
        
        int[] array = {1,2,3};
        
        umsortieren( array );
        
        /*Hier soll wieder die ursprüngliche Reihenfolge ausgegeben werden*/
        for(int i=0 ; i<array.length ; i++)
        System.out.print(array[i]);
    }
    
    public static void umsortieren(int[] a){
        
        int t = a[1];
        a[1] = a[2];
        a[2] = t;
    }
}

P.S. Wie kann ich hier im Forum ein "Danke" vergeben?
 
Hallo!

Nein.
Also schützen nicht.
Den Trick den du dazu benutzen kannst ist das du das ursprüngliche Array speicherst und ein zweites Array machst das umsortiert ist.

UND was ich jetzt sage merke dir!
hier funktioniert int[] newArray = oldArray; // Hier speicherst du die Referenz und das heißt:
// Wenn du eines der beiden änderst ändern sich beide
// Was du willst ist eine Kopie (Klon)

Hier ist der Beispiel code dafür

Java:
public class ArrayMod{
    
    
    public static void main(String[] args){
        
        int[] oldArray   = {1,2,3};              // Array wird deklariert und initialisiert
        int[] newArray = oldArray.clone();   // Hier deklarierst du eine neue Variable und speicherst den INHALT von oldArray in newArray (nicht die Referenz)
        
        umsortieren( newArray ); // Das neue Array wird umsortiert
        
        /*Hier soll wieder die ursprüngliche Reihenfolge ausgegeben werden*/
        for(int i=0 ; i< oldArray.length ; i++) {
          System.out.print(oldArray[i]);
        }
        System.out.println(""); // Hab ich eingebaut das es Zeilenabstand ist zwischen dem Output und dem der IDE
    }
    
    public static void umsortieren(int[] a){
        
        int t = a[1];
        a[1] = a[2];
        a[2] = t;
    }
}

In newArray ist das umsortierte Array (also der Inhalt)
Das ist ein neues Array mit neuer Referenz.

Warum du clone(); aufrufst kann ich dir einfach begründen, weil diese Funktion den Inhalt kopiert aber nicht die Referenz (Das ist was wir wollen).

Hoffe du kennst dich aus damit 🙂

Ums nochmal zusammenzufassen. Bei Arrays und Objekten wird mit dem = die Referenz übergeben, das heißt jede Veränderungen wird bei beiden Variablen übernommen, da sie beide auf das selbe Array hinweisen.
Willst du den Inhalt kopieren bei Objekten dann benutze .clone();
Dadurch hast du zwei unabhängige Objekte bzw. Arrays : )


LG

Rene


PS: Und zum Beispiel: Wenn dir Firma geht könnte Sie dir z.b etwas geben, das wäre dann der Rückgabetyp. Hoffe du verstehst was ich dir damit sagen will 😛

PSS: Wenn du nämlich oldArray mit newArray austausch in der For-Schleife wirst du merken das es klappt 😛.
 
Zuletzt bearbeitet:
Vielen Dank, Vancold!

Du kannst wirklich sehr gut erklären und weißt genau, was man noch zusätzlich bedenken sollte! 🙂
Hast mir sehr geholfen. Das Thema wäre damit erledigt.
 
Zuletzt bearbeitet:

Zurück
Oben