Problem mit Array in Java

le-koi

Cadet 2nd Year
Registriert
Nov. 2007
Beiträge
19
Hallo,

ich habe ein Problem in Java, welches ich mir leider selbst nicht erklären kann.
Ich habe ein static array in der Main-Methode definiert.
Ich möchte die Werte dieses Feldes an andere Felder in anderen Klassen zuweisen.
Soweit so gut (passiert im Bsp.-Programm über die set-Methode)
Wenn jetzt die 1. TestKlasse eine Veränderung vornimmt wird dies in dem
Feld der Main - Klasse gespeichert bzw. auch geändert! wieso???
Das Feld "startMatrix" hat keinen setter und ist privat.
Ich denke das es evtl. was damit zu tun hat das alles static ist, aber
erschließen kann ich es mir leider nicht

Vielen Dank im vorraus

Beispielcode für das Problem:

Code:
----------Main Klasse--------
package problem;

public class Main {

	private static final int ANZAHLKNOTEN = 16;
	private static int[][] startMatrix = new int[ANZAHLKNOTEN][ANZAHLKNOTEN];
	
	private static void ini()
	{
		startMatrix[0][1] = 3;
		startMatrix[0][2] = 5;
		startMatrix[0][4] = 6;
		startMatrix[1][0] = 3;
		startMatrix[1][4] = 4;
		startMatrix[2][0] = 5;
		startMatrix[2][3] = 2;
		startMatrix[2][4] = 5;
		startMatrix[3][2] = 2;
		startMatrix[3][6] = 5;
		startMatrix[4][0] = 6;
		startMatrix[4][1] = 4;
		startMatrix[4][2] = 5;
		startMatrix[4][5] = 4;
		startMatrix[4][6] = 3;
		startMatrix[4][9] = 4;
		startMatrix[5][1] = 4;
		startMatrix[5][4] = 4;
		startMatrix[5][9] = 4;
		startMatrix[6][3] = 5;
		startMatrix[6][4] = 3;
		startMatrix[6][7] = 8;
		startMatrix[6][8] = 3;
		startMatrix[6][10] = 6;
		startMatrix[7][6] = 8;
		startMatrix[7][8] = 5;
		startMatrix[7][10] = 3;
		startMatrix[7][13] = 5;
		startMatrix[7][15] = 12;
		startMatrix[8][6] = 3;
		startMatrix[8][7] = 5;
		startMatrix[8][9] = 6;
		startMatrix[8][13] = 5;
		startMatrix[9][5] = 4;
		startMatrix[9][8] = 6;
		startMatrix[10][6] = 6;
		startMatrix[11][13] = 5;
		startMatrix[12][7] = 5;
		startMatrix[12][10] = 5;
		startMatrix[12][13] = 8;
		startMatrix[12][14] = 3;
		startMatrix[12][15] = 11;
		startMatrix[13][7] = 5;
		startMatrix[13][8] = 5;
		startMatrix[13][11] = 5;
		startMatrix[13][12] = 8;
		startMatrix[14][12] = 3;
		startMatrix[14][15] = 7;
		startMatrix[15][7] = 12;
		startMatrix[15][11] = 5;
		startMatrix[15][14] = 7;

	}
	
	private static void ausgabe(int[][] matrix)
	{
	    for (int y= 0; y< ANZAHLKNOTEN ; y++)
	    {
	    	for (int x= 0; x< ANZAHLKNOTEN ; x++)
	    	{
	    		System.out.print(matrix[y][x]< 10 ? "  "+matrix[y][x] : " "+matrix[y][x]);			
	    	}
	    	System.out.println();
	    }
	    System.out.println();
	}
	
	public static void main(String[] args) {
		ini();
		
		Test1.setMatrix1(startMatrix);
		Test2.setMatrix2(startMatrix);
		
		Test1.verändern();
		ausgabe(Test1.getMatrix1());
		ausgabe(Test2.getMatrix2());

	}

}

----------Klasse Test 1--------

package problem;

public class Test1 
{
	private static final int ANZAHLKNOTEN = 16;
	private static int[][] Matrix1 = new int[ANZAHLKNOTEN][ANZAHLKNOTEN];
	
	public static void setMatrix1(int[][] matrix1) 
	{
		Matrix1 = matrix1;
	}
	
	public static void verändern()
	{
		Matrix1[0][0] = 2000;
		Matrix1[0][1] = 2000;
		Matrix1[1][0] = 2000;
	}

	public static int[][] getMatrix1() {
		return Matrix1;
	}
}

----------Klasse Test 2--------

package problem;

public class Test2 
{
	private static final int ANZAHLKNOTEN = 16;
	private static int[][] Matrix2 = new int[ANZAHLKNOTEN][ANZAHLKNOTEN];
	
	public static void setMatrix2(int[][] matrixI) 
	{
		Matrix2 = matrixI;
	}

	public static int[][] getMatrix2() 
	{
		return Matrix2;
	}
}
 
Ich kann das soweit erklären:
Das Array ist ein Objekt. Sobald du es in der Instanz von Test1 änderst, wird es auch in allen Instanzen (Main & Test 2) geändert.
Du müsstest schon unabhängige Arrays erzeugen und die Werte übergeben damit das klappt ;)

PS: Benutze bitte öfter den Tag this. und packe alle 3 Klassen in verschiedene "Code Fenster" ;)
 
Zuletzt bearbeitet:
Die Tatsache, dass es Objekte sind, klärt das ganze nicht wirklich auf...
Der Punkt ist, dass Variablen nur Referenzen auf Objekte sind, d.h. das Objekt, welches du als Parameter übergibst (viel mehr die referenzierende Variable) wird zwar kopiert, die Referenz geht aber noch auf das selbe Objekt. Also gilt alles, was du in der zweiten Variable (also Test-Klasse 1) machst für beide, da es sich nur um ein Objekt handelt (mit zwei Variablen, die sich aber halt auf das identische Objekt beziehen).

Die Lösung ist, den Aufruf
Test1.setMatrix1(startMatrix);
in eine Art
Test1.setMatrix1(startMatrix.clone());
zu ändern

damit hast du zwei eine weitere Matrix erschaffen, ein unabhängiges Objekt

Edit: Den zweiten Aufruf natürlich auch


Edit2: Zudem sind diese Zeilen hier im Grunde unnötig und können entschlackt werden:
private static final int ANZAHLKNOTEN = 16;
private static int[][] Matrix2 = new int[ANZAHLKNOTEN][ANZAHLKNOTEN];
kann man genauso in
private static int[][] Matrix2;
ändern...
(bei Matrix1 genauso)
 
Zuletzt bearbeitet:
Google mal "Daniel Noll Tutorial" da solltest du ein (gutes) Tutorial über VB.Net finden.
Da lies dir mal die Abschnitte zu ByRef und ByValue durch.
Ich meine der Knabe hat das ganz brauchbar erklährt.


Ansonsten:
Bei Primitiven Typen wird immer der Wert der Variable auf dem Stack abgelegt.
int a = 5 ;
int b = a;
a= 10;
--> b==5

Bei Objekten/Arrays/Strukturen/"nicht Primitiven Typen" wird die Addresse des Anfangs des belgten Speichers im Heap abgelegt.
int a[] = {1,2};
int b[] = {2,3};
a=b;
b[0]=12;

--> a[0] == 12
 
BennyBookworm, bei Java wird alles bei Value übergeben, bei Objekten sind es eben die Referenz-Werte (also die Ziel-Adresse).
 
Hab es jetzt Verstanden und es in meinen eigetnlichen Programm gelöst.

Vielen Dank an alle Helfer!
 
1668mib schrieb:
BennyBookworm, bei Java wird alles bei Value übergeben, bei Objekten sind es eben die Referenz-Werte (also die Ziel-Adresse).

Das ist schlicht und einfach Falsch.

Aber wie sind ja alle hier um zu lernen... :jumpin:
 
Hab ich halt hier gelesen und so übernommen, und für mich gibt das auch Sinn:
http://www.gungfu.de/facts/archives/2005/07/05/der-unterschied-zwischen-call-by-value-und-call-by-reference schrieb:
Java
Java ist irgendwie 'schwieriger' was die Parameterübergabe angeht. Andererseits auch ganz einfach: In Java werden Parameter immer per call-by-value übergeben...#

void f( int x ){
x = x * 2;
}
Da der Wert von x CBV übergeben wurde, bekommt der Aufrufer von einer Veränderung nichts mit.#

In Java ist zwischen primitiven Datentypen und Objekttypen zu unterscheiden. Wie sieht es also mit folgendem Code aus?#

void g( SomeObject x ){
x = new SomeObject()
}
Auch hier bekommt der Aufrufer nichts von der Änderung mit. Wieso? Das liegt daran, dass x zwar eine Referenz auf ein Objekt ist, diese Referenz allerdings per call-by-value übergeben wurde. D.h. sie wurde kopiert. Bei der Parameterübergabe hat man also zwei Referenzen, die auf dasselbe Objekt zeigen. Im Gegensatz zu einer Referenz (in zwei Variablen), die auf dasselbe Objekt zeigen, im Falle von C++ und dem Referenzoperator.#

Ich lasse mich aber gerne eines besseren belehren.
 
Joa, bei Methoden stimmt das meines Wissens auch.
Und bei einem Array probier ich das jetzt erstma aus bevor ich was falsches gesagt habe.
;)
 
Ähm was ich oben geschrieben habe mit "alles by value" bezog sich ja auf Parameter bei Methoden-Aufrufen.

Aber gerade das Beispiel mit void g( SomeObject x ) zeigt, dass selbst Objektvariablen by value und nicht by reference übergeben werden. Man muss sich nur vor Augen führen: Nicht das Objekt selbst wird kopiert, sondern lediglich der Verweis auf das Objekt. Wäre es das Objekt selbst, würde eine Zuweisung auch das Ursprüngliche Objekt "ersetzen"... das passiert allerdings nicht.
 
Zurück
Oben