# Werte von Variablen über Methode ändern



## DDyrdek1992 (16. Jul 2014)

Hallo,

Meine Frage ist, wie kann ich zwei Werte aus meiner main-Methode in einer aufgerufenen Klassenmethode ändern? Im folgenden Quellcode werden in der main-Methode zwei Variablen initialisert und sollen in einer Methode vertauscht werden. Die Werte werden innerhalb der Methode aber nur lokal vertauscht und die Variablen der main-Methode behalten ihre Werte. Man könnte die Aufgabe aus dem Quellcode auch anders lösen, aber mich interessiert ob ich irgendwie die beiden Variablen wirklich über eine Methode verändern kann. return von zwei Werten geht ja nicht.

Danke schonmal für jede Hilfe! 


```
static void tausche (int a, int b) {
// vertauscht a und b
int c = a;
a = b;
b = c;
}
public static void main (String[] args) {
int x = 4, y = 0;
if (y == 0) tausche(x,y);
x = x / y;
}
```


----------



## stg (16. Jul 2014)

Kurz: Gar nicht, weil in Java alle Aufrufe "by Value" stattfinden. 

Du musst dir heirfür leider einen Workaround basteln und zum Beispiel die Werte in einen mutable Datentyp (die Wrapper sind immutable, da bekommst du also das gleiche Problem!) packen und diesen dann übergeben. Dann kannst du zwar auch nicht die übergebenen Container tauschen, aber deren Inhalt.


----------



## SilverClaw (16. Jul 2014)

Mir erschleßt sich der Sinn der Methode nicht ganz...du willst also z.B. die Werte von 5 und 3 tauschen und deine Methode tauscht die Speicheraddresen dafür....da könntest du doch genau so gut einfach die Zahlen anders herum hinschreiben. Oder hab ich was verpasst? 

Sinnvoll wäre das eher, wenn die Zahlen z.B. in einem Array an bestimten stellen stehen. Dann könntest du auch als Parameter den Array übergeben und die Methode tauscht die Positionen und das bleibt dann auch so.


----------



## DDyrdek1992 (16. Jul 2014)

Zur Erklärung vielleicht war das eine Aufgabe in der man einen Laufzeitfehler erkennen sollte. Mir war klar dass das so nicht funktionieren konnte, wollte aber wissen ob man allgemein die Variablen hier über eine Methode ändern könnte. Also es geht jetzt nicht speziell um dieses Beispiel


----------



## husox123 (16. Jul 2014)

Man kann wohl die Werte von Variablen über Methoden ändern. Allerdings sollte es mit bedacht machen. 
Es stimmt, dass Java mit Call-By-Value Verfahren arbeitet bis auf Referenz-Datentypen, zu dem auch die Array zählen. Also wenn du die beiden Variablen als Array übergibst, werden die Adressen übergeben und somit alle Veränderungen auf der tatsächlichen Adressen statt finden. Damit bekommst du den Effekt, den du haben wolltest, aber unschön.


----------



## stg (16. Jul 2014)

husox123 hat gesagt.:


> Es stimmt, dass Java mit Call-By-Value Verfahren arbeitet bis auf Referenz-Datentypen



Java arbeitet IMMER mit Call-By-Value, ohne Ausnahme. Man muss nur verstehen, was das bedeutet. Man übergibt nämlich den Methoden keine Objekte, sondern nur Referrenzen auf diese, und zwar By-Value.


----------



## husox123 (17. Jul 2014)

stg hat gesagt.:


> Java arbeitet IMMER mit Call-By-Value, ohne Ausnahme. Man muss nur verstehen, was das bedeutet. Man übergibt nämlich den Methoden keine Objekte, sondern nur Referrenzen auf diese, und zwar By-Value.



Also wenn man Referenzen über gibt, arbeitet man auch mit Call-By-Value. Stimmt. Was aber heißt, dass Java eine Kopie von der übergebenen Referenz erstellt, was bei Arrays der Fall ist.  Diese werden als Referenz übergeben und beziehen sich daher immer auf das Original-Objekt. Wird das übergebene Objekt manipuliert, so ändert sich auch der Zustand des Originals. Wenn ich falsch liege, dann korrigiert mich bitte. :rtfm:


----------



## Anti-Banane (17. Jul 2014)

ja .. du liegst falsch

in java sind arrays letzten endes auch nur mutable objekte

call-by-value bedeutet in java das die adresse auf die eine referenz zeigt kopiert und übergeben wird

ergo : wenn man ein "array" übergibt wird lediglich die adresse auf die die referenz zeigt kopiert und übergeben
das heißt also das es dann keine zwei arrays gibt die auf magische weise mit ein ander synchronisiert werden sondern lediglich zwei stellen im stack die als speicher-adresse makiert sind und auf den selben speicher-bereich verweisen

die aussage "Wird das übergebene Objekt manipuliert, so ändert sich auch der Zustand des Originals." ist in sofern falsch das es eben dieses "übergeben objekt" schlicht nicht gibt sondern die übergebene kopie der referenz auf das einzige bestehende (und damit im kontext der aussage "originale") objekt zeigt


----------



## husox123 (17. Jul 2014)

Anti-Banane hat gesagt.:


> ja .. du liegst falsch
> 
> in java sind arrays letzten endes auch nur mutable objekte
> 
> ...



Ich glaube, dass du die Aussage falsch verstanden hast. genau das was du sagst, beschreibe ich auch. und sie ist Richtig. Die Referenz wird kopiert und die Kopie der Referenz zeigt auf das selbe Object. Und somit finden alle Veränderungen auf dem originalen Objekt. "Hier sind die Arrays gemeint."  Ich habe nirgendwo erwähnt, dass das Array kopiert wird. Ich gebe zu das folgende erweckt Missverständnis. 

 "Wird das übergebene Objekt manipuliert, so ändert sich auch der Zustand des Originals"

Damit ist nicht eine Kopie gemeint.


----------



## ceving (18. Jul 2014)

DDyrdek1992 hat gesagt.:


> Meine Frage ist, wie kann ich zwei Werte aus meiner main-Methode in einer aufgerufenen Klassenmethode ändern?



Mit einem Wert wie einem 
	
	
	
	





```
int
```
 geht das nicht. Du musst ein sog. Boxing und Unboxing machen. Du brauchst also zwei Kisten für deine beiden "int"s und kannst an "tausche" die beiden Kisten übergeben. "tausche" ist dann in der Lage den Inhalt der beiden Kisten zu tauschen. Die Kisten selber kann "tausche" auch nicht vertauschen wie andere ja schon erläutert haben (Call by value).

Beispiel:

```
class tausche
{
  static class Int
  {
    int value;
    Int (int value) { this.value = value; }
    boolean equal (int i) { return this.value == i; }
    void div (Int other) { value = this.value / other.value; }
    void dump (String label) {
      System.out.println (label + ": " + String.valueOf(value));
    }
  }

  static void tausche (Int a, Int b) {
    // vertauscht a und b
    int c = a.value;
    a.value = b.value;
    b.value = c;
  }

  static void println (String str) { System.out.println (str); }

  public static void main (String[] args) {
    Int x = new Int(4), y = new Int(0);
    x.dump ("x"); y.dump ("y");
    //if (y == 0) tausche(x,y);
    //x = x / y;
    if (y.equal(0)) tausche (x, y);
    x.dump ("x"); y.dump ("y");
    x.div (y);
    x.dump ("x"); y.dump ("y");
  }
}
```

Da man in Java keine Operatoren überladen kann, müssen alle Operationen (hier == und /), die für die Werte definiert waren für die Boxen neu programmiert werden. Etwas ähnliches macht Java bereits bei dem Objekt-Typ Integer. Insbesondere findet für Integer sogar ein Auto-Boxing statt.


----------



## Anti-Banane (18. Jul 2014)

husox123 hat gesagt.:


> "Wird das übergebene Objekt manipuliert, so ändert sich auch der Zustand des Originals"



sorry .. aber für mich sind DAS zwei objekte "das übergebene" und "das original" ... wobei es eben "das übergebene objekt" halt nicht gibt da wie du schon richtig gesagt hast die referenz eh auf das "original" zeigt ... und es damit halt nur EIN objekt gibt


der sinn deiner aussage mag richtig sein ... wie du es allerdings ausgedrückt hast klingt irgendwie ziemlich schwammig


----------

