# Methode: ArrayList byRef übergeben



## xray200 (13. Aug 2009)

Hallo,

ich stehe etwas auf dem Schlauch: ich habe eine Funktion, die als Parameter eine ArrayList erhält, deren Inhalt modifiziert wird.
Die Funktion gibt ein Boolean zurück und soll die Weiterverwendung der ArrayList ermöglichen.

Die Inhalte der ArrayList kann der Aufrufer aber nicht "sehen", er bekommt nur die in der Funktion initialisierte ArrayList ohne Inhalt zurück.

Wird das nicht byRef übergeben, sollte das nicht gehen oder geht es nur bei Mehtoden ohne Rückgabewert?a


----------



## Wildcard (13. Aug 2009)

Alles in Java ist call by value, allerdings ist der Value nicht das Objekt, sondern die Referenz auf das Objekt. Sprich: manipulierst du ein übergebenes List Objekt, dann sind die Änderungen für den Aufrufer auch sichtbar.


----------



## bygones (13. Aug 2009)

hae ? 

bygones

Objekte werden per *hust" Referenz (gibt es in Java nur leider nicht) uebergeben und somit sind veraenderungen sichtbar...


----------



## xray200 (13. Aug 2009)

bygones hat gesagt.:


> hae ?
> 
> bygones
> 
> Objekte werden per *hust" Referenz (gibt es in Java nur leider nicht) uebergeben und somit sind veraenderungen sichtbar...



Ich initialisiere die ArrayList, die per Parameter (also als Referenz) übergeben wird in der Funktion neu und fülle sie mit Inhalt. 

Das müsste doch gehen, oder, ich muss die Liste weiterverarbeiten könne mit den Inhalten?


```
public static Boolean check(ArrayList<String> liste){
		
		liste=new ArrayList<String>();
		
		liste.add("Test");
		return true;
	}
```


----------



## bygones (13. Aug 2009)

fuer mich ist das code smell...

warum bekomme ich eine Liste als Parameter, wenn diese dann so und so neu erstellt wird... und warum gibt es dann noch true zurueck ?!

entweder ist das nur ein bsp, auch dann ist es aber merkwuerdig


----------



## xray200 (13. Aug 2009)

Ist jetzt nur ein Teil des Codes, sie wird unter umständen neu initialisiert und sollte dann weiterverwendet werden.

Warum geht das so nicht bei mir? Sollte es?


----------



## tfa (13. Aug 2009)

Du missbrauchst den Methodenparameter als lokale Variable. Wenn die Methode zurück kehrt, ist die neu angelegte ArrayList weg, da das Objekt außerhalb nicht mehr sichtbar ist. Es gibt kein Call-by-Reference in Java.
Du könntest aber clear() auf die (übergebene) Liste aufrufen, um sie zu löschen.


----------



## xray200 (13. Aug 2009)

tfa hat gesagt.:


> Du missbrauchst den Methodenparameter als lokale Variable. Wenn die Methode zurück kehrt, ist die neu angelegte ArrayList weg, da das Objekt außerhalb nicht mehr sichtbar ist. Es gibt kein Call-by-Reference in Java.
> Du könntest aber clear() auf die (übergebene) Liste aufrufen, um sie zu löschen.



Ich möchte einfach nicht nur Boolean zurückgeben, sondern auch den ggf. bearbeiteten oder neu initialisierten Inhalt der ArrayList.

Wie mache ich das am besten?


----------



## Michael... (13. Aug 2009)

Deine Variable liste in der Methode ist quasi eine "lokale" Variable, d.h. die Liste die Du in der Methode erstellst ist nur innerhalb der Methode bekannt und entspricht nicht mehr der ursprunglichen Liste. Entweder Du machst es so

```
public list ArrayList<String>;
public boolean check(){
        list=new ArrayList<String>();
        list.add("Test");
        return true;
}
```
oder

```
public static boolean check(ArrayList<String> list){
        list.clear();
        list.add("Test");
        return true;
}
```


----------



## xray200 (13. Aug 2009)

OK, ich dachte ich könnte sie in der Funktion auch neu initialisieren. (Dein 2. Bsp)

D.h. mit clear() wird sie nicht neu initialisiert. Das mache ich immer außerhalb richtig?


----------



## Michael... (13. Aug 2009)

In Bsp1 wird eine neue Instanz erzeugt und der Variablen list zugewiesen.
In Bsp2 wird die bestehende Intstanz geleert und weiter verwendet.
Die Frage verstehe ich nicht. Was ist außerhalb und was machst Du da?


xray200 hat gesagt.:


> Das mache ich immer außerhalb richtig?


----------



## xray200 (13. Aug 2009)

Michael... hat gesagt.:


> In Bsp1 wird eine neue Instanz erzeugt und der Variablen list zugewiesen.
> In Bsp2 wird die bestehende Intstanz geleert und weiter verwendet.
> Die Frage verstehe ich nicht. Was ist außerhalb und was machst Du da?



Mit Außerhalb meinte ich den Aufrufer. Das passt also.

Wobei ich mich frage: geht es nie, innerhalb einer Funktion einen Parameter neu zu initialiseren, den ich extern, außerhalb, also durch den Aufrufer dann noch verwenden will?


----------



## Wildcard (13. Aug 2009)

Nein, dann das wäre Call-By-Reference, welches in Java nicht vorkommt. Du kannst das übergebene Objekt manipulieren, aber nicht die übergebene Referenz umbiegen, denn das ist nur eine Kopie.


----------



## xray200 (13. Aug 2009)

Bei primitiven Datentypen kann ich aber den Parameter nicht modifizieren und weiterverwenden, da nur perValue übergeben oder?


----------



## bygones (13. Aug 2009)

xray200 hat gesagt.:


> Bei primitiven Datentypen kann ich aber den Parameter nicht modifizieren und weiterverwenden, da nur perValue übergeben oder?



*ALLES* in java wird byValue uebergeben es gibt KEIN byReference... egal primtiv oder objekte

natuerlich kannst du einen gegeben Wert manipulieren und weiterverwenden (egal ob primitiv oder Objekt)... die Frage ist was der Aufrufer sieht.


----------



## Schandro (13. Aug 2009)

Variablen von Primitive Datentypen (und z.b. Strings, da immutable) können nicht durch "als Parameter übergeben" verändert werden, ja.

Alles wird "per Value" übergeben, bei nicht-primitiven Datentypen ist das halt der Value der Referenz ansich.


----------



## xray200 (14. Aug 2009)

Kann ich denn ein Objekt in einer Methode erzeugen und dann mit einem externen Objekt "verlinken", also folgendes:

[Java]
public static ArrayList Sammlung=new ArrayList();

public void methode(){
ArrayList neueListe=new ArrayList();

//neueListe bearbeiten
Sammlung.add(neueListe)
}
[/Java]


----------



## maki (14. Aug 2009)

.addAll


----------



## xray200 (21. Aug 2009)

Hallo, nun habe ich nochmal eine Nachfrage zum byRef, byValue Problem:

Ich benötige eine Methode, die einen int und drei Booleanwerte zurückgibt.

Also habe ich "return int" und sowie als Parameter für die Booleanrückgabe den Array "boolean[] speicher" 

Der Array wird schon initialisiert übergeben.
In der Funktion mache ich dann
speicher[0]=... speicher[1]=... speicher[2]=...

Das sollte doch gehen oder?


Geht das dann auch, wenn das ein Array mit meinen Objekten ist und ich diese in der Funktion neu erzeuge, also:

speicher[1]=new meinObjekt();

Ich erhalte soweit ich das sehe dann nur als Rückgabe speicher[1]=null beim Aufrufer der Funktion. 

Wie löse ich denn das am besten?


----------



## SlaterB (21. Aug 2009)

geht auch mit Objekten, das Array kann nicht neu zugewiesen werden, darf aber beliebig verändert werden


----------



## faetzminator (21. Aug 2009)

Ja das funktioniert. Du musst dir vorstellen, dass du immer Call bei Value hast. Bei einem nicht primitiven Datentyp (auch Arrays mit primitiven Datentypen) übergibst du als Value die Referenz auf jenes Objekt. Wenn du [c]x = new Foo()[/c] aufrufst, wird ein neues Foo erstellt und die Referenz davon in x gemerkt. Solange du aber die Referenz nicht anpasst, kannst du mit dem Objekt (also auch boolean[]) machen was du willst, der Aufrufer wird die Änderungen mitbekommen, da es ja das gleiche Objekt ist.


----------



## Painii (21. Aug 2009)

Wenn du in der Methode ein neues Objekt baust ist das nach aussen nicht zu sehen:


```
public void macheWas(boolean[] array){
 array = new boolean[1];
}
public static void main(String[] args){
 boolean[] a = new boolean[2];
 macheWas(a);
 boolean.length==2; //true
}
```

Wenn du das Attribut des Objekts veränderst ist das zu sehen!

```
public void macheWas(boolean[] array){
 array[0]=true;
}
public static void main(String[] args){
 boolean[] a = {false};
 macheWas(a);
 boolean[1]==true; //true
}
```


----------



## Leroy42 (21. Aug 2009)

Painii hat gesagt.:


> ```
> public void macheWas(boolean[] array){
> array[0]=true;
> }
> ...



Du meintest wohl


```
public void macheWas(boolean[] array){
 array[0]=true;
}
public static void main(String[] args){
 boolean[] a = {false};
 macheWas(a);
 a[0]==true; //true
}
```


----------

