# Array von Vektoren by reference übergeben



## benner (10. Jan 2007)

Hallo zusammen. 
Ich wollte folgendes tun: in der Klasse GUI erzeuge ich ein Array von Vektoren. Es müssen Vektoren sein und kein 2-dimensionales Array, da nicht feststeht, wie viele Werte da rein sollen. Dieses Array möchte ich jetzt an verschiedene Klassen übergeben und ihm einige Elemente hinzufügen/löschen, dieses neue Vektorfeld dann wieder in GUI ablegen. Dafür bietet sich ja eine Übergabe by reference an oder?

Ich habe mich ein bisschen schlau gemacht und erfahren, dass Objekte (also auch mein Array?) immer by reference übergeben werden. Deswegen habe ich folgendes geschrieben(Auszug): 


```
public class Gui extends JFrame
{
        Dialog dialog;
        public Vector[] data = new Vector[4]; 
		
        Gui(int width, int height)
        {
            dialog = new Dialog(this,data);
        }
}
```


```
public class Dialog extends JDialog
{
            Dialog(final JFrame f,Vector[] data)
            {
                super(f,"Add data record",true);
                bAdd.setBounds(450,300,100,30);b
                Add.setText("Add!");
                bAdd.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae1)
                {
                    if( tfAuthor.getText().equals("") ||
                        tfTitle.getText().equals("") ||
                        cbSw1.getSelectedItem().toString().equals("") ||
                        cbSw2.getSelectedItem().toString().equals(""))
                    {
                        JOptionPane.showMessageDialog(
                                Dialog.this,
                                "Please fill in all the necessary information",
                                "Error",
                                JOptionPane.ERROR_MESSAGE);
                    }
                    else
                    {
                        //hier wird der Inhalt diverser ComboBoxes und TextFields hinzugefügt...
                        data[0].addElement(Dialog.this.cbSw1.getSelectedItem().toString());
                        data[1].addElement(Dialog.this.cbSw2.getSelectedItem().toString());
                        data[2].addElement(Dialog.this.tfAuthor.getText().toString());
                        data[3].addElement(Dialog.this.tfTitle.getText().toString());

                        JOptionPane.showMessageDialog(
                                Dialog.this,
                                "Data record was added to library.",
                                "Congratulations",
                                JOptionPane.INFORMATION_MESSAGE);
                    }
                }
                });
            }
}
```

Ich habe die Beispiele nur auf das nötigste zusammengeschrumpft, ich hoffe das ist trotzdem ausreichend. Wenn nicht, kann ich ja noch mehr posten. 

Ich erhalte jetzt eine Fehlermeldung die da sagt: "Cannot refer to a non-final variable data inside an inner class defined in a different method".
Ich habe mal probiert, den Konstruktor von Dialog so zu ändern: Dialog(final JFrame f,final Vector[] data) und siehe da, es ging auf einmal. Aber jetzt habe ich Bedenken: final bewirkt doch eigentlich, dass eine Variable nicht mehr geändert werden kann. Aber genau das möchte ich doch  :autsch: Und bezieht sich dieses nicht-ändern dann nur auf die Klasse Dialog oder auf alle Klassen? Ich hab final noch nie benutzt und bin mir deswegen sehr unsicher. 

Gibt es vielleicht noch einen besseren Ansatz das Problem zu lösen?


----------



## hupfdule (10. Jan 2007)

benner hat gesagt.:
			
		

> Es müssen Vektoren sein


Nein, es muss eine java.util.List sein. Zum Beispiel ArrayList. Vectoren benutzt man in Java kaum, da diese synchronisiert sind, was sehr selten gebraucht wird. Hat aber mit deinem Problem nichts zu tun. 



> Ich habe mich ein bisschen schlau gemacht und erfahren, dass Objekte (also auch mein Array?) immer by reference übergeben werden.


Korrekt.



> Ich erhalte jetzt eine Fehlermeldung die da sagt: "Cannot refer to a non-final variable data inside an inner class defined in a different method".
> Ich habe mal probiert, den Konstruktor von Dialog so zu ändern: Dialog(final JFrame f,final Vector[] data) und siehe da, es ging auf einmal.


War auch die richtige Aktion.


> Aber jetzt habe ich Bedenken: final bewirkt doch eigentlich, dass eine Variable nicht mehr geändert werden kann. Aber genau das möchte ich doch  :autsch: Und bezieht sich dieses nicht-ändern dann nur auf die Klasse Dialog oder auf alle Klassen? Ich hab final noch nie benutzt und bin mir deswegen sehr unsicher.


Hier hast du ein Verständnisproblem. Das final bedeutet nur, dass du dieser Variablen (nicht dem dahinter stehenden Objekt!) nichts mehr zuweisen kannst. Du kannst also nicht irgendwann in dieser Methode schreiben data= new Vector[]. Und das wirkt sich natürlich auch nur auf den Gültigkeitsbereich dieser Variablen aus.


> Gibt es vielleicht noch einen besseren Ansatz das Problem zu lösen?



Deinen Code hab ich zwar nicht angeguckt, laut deiner Beschreibung hast du das aber schon richtig gemacht (bis auf den Vector ;-)).


----------



## Wildcard (10. Jan 2007)

1. In Java wird nichts per Referenz, sondern immer per Value.
Bei primitiven Datentypen der Wert der Variablen, bei Objekten eine Kopie der Referenz.
2. Das final bewirk bei Objekten lediglich das die Variable nicht neu referenziert werden darf, also das f plötzlich auf einen neuen JFrame zeigt.
3. Du brauchst mit Sicherheit keinen Vector. Das ist eine recht alte und ziemlich miese Implementierung, da sich nachträglich an die Collection API angepasst wurde.
Nimm statt des Vectors lieber ArrayList, oder LinkedList, o.ä.


----------



## benner (10. Jan 2007)

OK vielen Dank an euch beide. Vor allem für die Aufklärung des Verständnisproblems mit final. Ich denke ich sollte das Problem jetzt in den Griff bekommen


----------



## Leroy42 (10. Jan 2007)

hupfdule hat gesagt.:
			
		

> > Ich habe mich ein bisschen schlau gemacht und erfahren, dass Objekte (also auch mein Array?) immer by reference übergeben werden.
> 
> 
> Korrekt.



Eben nicht!

Alles wird in Java per call-by-value übergeben:


```
void methode (String erna) {erna = "hugo";}

...

String emil = "detlev";
methode(emil);
// emil verweist nach wie vor auf "detlev"
```

Würde der String by-reference übergeben, müßte 
emil nach Aufruf auf "hugo" verweisen, was es nicht tut.


----------



## byte (10. Jan 2007)

> Dieses Array möchte ich jetzt an verschiedene Klassen übergeben und ihm einige Elemente hinzufügen/löschen, dieses neue Vektorfeld dann wieder in GUI ablegen.



Das kannst Du trotz fehlendem Call By Reference so machen. Wenn Du ein Objekt an eine Methode übergibst, dann wird zwar die Referenz kopiert, sie zeigt aber natürlich weiterhin aufs gleiche Objekt im Speicher. Wenn Du dieses Objekt also nun manipulierst (z.B. bei einer Collection mit remove oder add), dann hat diese Veränderung sehr wohl Seiteneffekte auf alle Referenzen, die ebenfalls auf dieses Objekt zeigen.


----------

