# NullPointerException



## Lange (6. Jan 2011)

Hallo, ich möchte ein Element aus einem stack Stapel mit einer methode ziehen und weiterverarbeiten. Beim weiterverarbeiten bekomme ich folgende Fehlermeldung: 

Karte gezogen: 5
Exception in thread "main" java.lang.NullPointerException
        at Spiel.<init>(Kartenspiel3.java:31)
        at Kartenspiel3.main(Kartenspiel3.java:9)

Warum funktioniert das nicht, obwohl Objekte in der methode übergeben werden?
Wie löst man das Problem?


```
/* Kartenspiel.java */

import java.io.*;


class Kartenspiel3 {
  public static void main(String[] args) throws IOException {

     Spiel spiel = new Spiel();
  }
}



class Spiel {

  Stapel schleckMartin = new Stapel(4);
  Stapel ablageMartin  = new Stapel(8);

  Karte martinsKarte;

  Spieler martin = new Spieler();


  Spiel ()  {
      schleckMartin.push(new Karte(7));
      schleckMartin.push(new Karte(5));

       martin.schleckKarte(martinsKarte, schleckMartin);
   
       martinsKarte.print();
  }
}



class Spieler {

  Karte spielerKarte;
  Stapel schleckSpieler; 
  
  
     Spieler () {
     }

     void schleckKarte(Karte spielerK, Stapel schleckSp) {
       spielerKarte = spielerK;
       schleckSpieler = schleckSp;

       spielerKarte = schleckSpieler.pop();
       System.out.print("Karte gezogen: ");
       spielerKarte.print();
     }
}



class Stapel {

  private Karte[] array;
  private int top = 0;
  public Stapel(int nr) {
    array = new Karte[nr];
  }

  public void push(Karte element) {
    array[top++] = element;
  }

  public Karte pop() {
    return array[--top];
  }

}

class Karte {

  int wert;
  
  public Karte(int wert) {
    this.wert = wert;
  }
  public void print() {
    System.out.println(wert);
  }
 
}
```


----------



## VfL_Freak (6. Jan 2011)

Moin,



Lange hat gesagt.:


> Warum funktioniert das nicht, obwohl Objekte in der methode übergeben werden?



Nein, machst Du nicht :noe:
Du deklariert in *main()* lediglich eine Variable "Karte martinsKarte" !
Jetzt ist diese erstmal null !

Du würdest hier sowas brauchen :

```
Karte martinsKarte = new Karte();
// oder besser :
Karte martinsKarte = new Karte( wert ); // was auch immer das hier ist
```

Denn anschließend übergibst Du Variable an die Methode "martin.schleckKarte(..)" ohne Rückgabe.
Also bekommst nach dem Aufruf die NPE ...

Gruß
Klaus


----------



## Lange (6. Jan 2011)

Ok, die NPE ist nun weg, aber mein Problem ist immer noch, dass das Objekt martinsKarte nach dem Aufruf der methode martin.schleckKarte(martinsKarte, schleckMartin); unverändert ist.

Karte gezogen: 5
1    <--  sollte 5 sein.

Ich will, dass das Ergebnis von spielerKarte = schleckSpieler.pop(); im Aufruf der Methode martin.schleckKarte(martinsKarte, schleckMartin); verwendet wird! 


```
/* Kartenspiel.java */

import java.io.*;


class Kartenspiel4 {
  public static void main(String[] args) throws IOException {

     Spiel spiel = new Spiel();
  }
}



class Spiel {

  Stapel schleckMartin = new Stapel(4);
  Stapel ablageMartin  = new Stapel(8);

  Karte martinsKarte = new Karte(1);  // erzeuge Objekt.

  Spieler martin = new Spieler();


  Spiel ()  {
      schleckMartin.push(new Karte(7));  // zweite Karte
      schleckMartin.push(new Karte(5));  // erste Karte

       martin.schleckKarte(martinsKarte, schleckMartin); // ziehe z.B 5 als erste Karte.
   
       martinsKarte.print();  // erwarte wert 5 von erste Karte, 
                              // bekomme aber wert 1 von der ursprünglichen Erzeugung des Objekts.
  }
}



class Spieler {

 public Karte spielerKarte;
 public Stapel schleckSpieler; 
  
  
     Spieler () {
     }

     public void schleckKarte(Karte spielerK, Stapel schleckSp) {
       schleckSpieler = schleckSp;

       spielerKarte = schleckSpieler.pop();
       System.out.print("Karte gezogen: ");
       spielerKarte.print();
     }
}
```


----------



## Andi_CH (6. Jan 2011)

ich sehe nicht, dass du in der Methode schleckKarte mit der Karte (die da seltsamerweise spielerK heisst???) irgendetwas machst - kein Wunder ist die unverändert ...


----------



## VfL_Freak (6. Jan 2011)

Moin,



Lange hat gesagt.:


> Ok, die NPE ist nun weg, aber mein Problem ist immer noch, dass das Objekt martinsKarte nach dem Aufruf der methode martin.schleckKarte(martinsKarte, schleckMartin); unverändert ist.
> 
> Karte gezogen: 5
> 1    <--  sollte 5 sein.
> ...



Nun, Du verändert den Wert von *spielerkarte *in *Spiel()* ja auch gar nicht --> ergo immer noch 1.Wie ich schon am Anfang schrieb, muss *martinsKarte * von der Methode *martin.schleckKarte* zurückgegeben !


```
return spielerK;
```
wäre hier das richtige Stichwort ... warum auch das an der Stelle so heißt 
Glaub' mir, in einem halben Jahr weißt Du selbst nicht mehr, was Dein Code macht .....

Gruß
Klaus


----------



## Andi_CH (6. Jan 2011)

VfL_Freak hat gesagt.:


> Wie ich schon am Anfang schrieb, muss *martinsKarte * von der Methode *martin.schleckKarte* zurückgegeben !
> 
> 
> ```
> ...


Muss sie nicht zwingend, auch wenn das der bessere Stil wäre als das Folgende ;-)



```
private static class Karte {
	private int mWert = 0;
	public void setWert(int pWert) {
		mWert = pWert;
	}
	@Override
	public String toString() {
		return "" + mWert;
	}
}

private static void changeValue (Karte pKarte, int pValue) {
	pKarte.setWert(pValue);
}

public static void main(String[] args) {
	System.out.println("Karte");
	Karte mKarte = new Karte();
	mKarte.setWert(1);
	System.out.println("Kartenwert = " + mKarte);
	changeValue(mKarte, 2);
	System.out.println("Kartenwert = " + mKarte);
}
```

Output:

```
Karte
Kartenwert = 1
Kartenwert = 2
```


----------



## Lange (6. Jan 2011)

Danke für die Hilfe.

mit Rückgabewert einer Karte funktioniert es.
Gibt es eine Möglichkeit mehrere Rückgabewerte unterschiedlicher Typen z.B hier von Karte, boolean und Stapel, in einer Methode unterzubringen?


----------



## VfL_Freak (6. Jan 2011)

Moin,

nein, Du kannst immer nur genau EINEN Datentyp/Objekt zurückgeben.
Aber Du darfst Dir natürlich eigene Datentypen basteln 
Erstelle einen Klasse mit entsprechenden Membervariablen, erzeuge eine Instanz davon, übergib sie an Deine gewünschte Methode, fülle dort die Membervariablen und gib' die Instanz wieder zurück !

gruß
Klaus


----------

