# NullPointerException bei Übergabe an eine Methode



## webix (25. Mai 2004)

Hallo,

ich habe ein Problem beim Aufruf einer Methode aus meiner Hauptklasse.

Hauptklasse:

import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Geburtstag extends Frame implements ActionListener
{

// Buttons, Textfelder werden hier definiert

AdressListe liste; //Das ist meine Unterklasse

public Geburtstag(AdressListe liste)
{
	super ("Geburtstag");
	this.setSize(600,480);
	this.setLayout(null);
	this.liste = liste;
}

public void auslesen(){

}

public static void main (String Args[])
{
	AdressListe liste = new AdressListe();
	liste.adresseAuslesen();
	Geburtstag f = new Geburtstag(liste);
	f.show();
}

}

Meine Unterklasse

import java.util.*;
import java.util.Vector.*;
import java.io.*;


public class AdressListe extends Vector
{

Geburtstag geb;

 public void adresseEintragen(Geburtstage temp)
  {
    this.add(temp); //Liste wird hinzugefügt
  }

  public void adresseAuslesen (){

geb.auslesen();  //Aufruf der Methode aus der Hauptklasse

}

Folgende NullPointerExcpetion wird beim Kompilieren ausgegeben:

Exception in thread "main" java.lang.NullPointerException 
at AdressListe.adresseAuslesen<geb.auslesen();>// In der Methode adresseAuslesen
at Geburtstag.main<liste.adresseAuslesen();> //Unten in der MainMethode der Hauptklasse


----------



## Snape (25. Mai 2004)

> _Original geschrieben von webix _
> *Hallo,
> 
> ich habe ein Problem beim Aufruf einer Methode aus meiner Hauptklasse.
> ...



So lange Du nirgends adresseEintragen(...) aufrufst, bleibt die Variable geb natürlich immer NULL und geb.auslesen(); wirft logischerweise eine NullPointerException.


----------



## webix (25. Mai 2004)

*Hallo*

liste.adresseEintragen wird bei mir aufgerufen, wenn ich ein Button drücke, ich habs hier aber nicht reingesetzt, da ich denke, dass es nicht daran liegt, da adresseEintragen eine eigene Methode ist.

Folgende NullPointerExcpetion wird beim Kompilieren ausgegeben:

Exception in thread "main" java.lang.NullPointerException 
at AdressListe.adresseAuslesen<geb.auslesen();>// In der Methode adresseAuslesen
at Geburtstag.main<liste.adresseAuslesen();> //Unten in der MainMethode der Hauptklasse


----------



## Snape (25. Mai 2004)

*Re: Hallo*



> _Original geschrieben von webix _
> liste.adresseEintragen wird bei mir aufgerufen, wenn ich ein Button drücke, ich habs hier aber nicht reingesetzt, da ich denke, dass es nicht daran liegt, da adresseEintragen eine eigene Methode ist.



So lange Du aber den Button nicht drückst, bleibt geb = NULL.



> Folgende NullPointerExcpetion wird beim Kompilieren ausgegeben:
> 
> Exception in thread "main" java.lang.NullPointerException
> at AdressListe.adresseAuslesen<geb.auslesen();>// In der Methode adresseAuslesen
> at Geburtstag.main<liste.adresseAuslesen();> //Unten in der MainMethode der Hauptklasse



Diese Fehlermeldung würde ich immer noch so interpretieren, dass geb.auslesen() den NP wirft, ergo geb = NULL ist. Was mich erneut zu der bereits o.a. Vermutung führt.


----------



## webix (25. Mai 2004)

Du meinst, weil in adresseAuslesen aus der Klasse AdressListe keine Daten in der Methode vorhanden sind?

Es sind abwer welche vorhanden, ich kann ja auch manuel eine Variable erzeugen und übergeben lassen. Oder reden wir einander vorbei?


----------



## Snape (25. Mai 2004)

> _Original geschrieben von webix _
> *Du meinst, weil in adresseAuslesen aus der Klasse AdressListe keine Daten in der Methode vorhanden sind?
> 
> Es sind abwer welche vorhanden, ich kann ja auch manuel eine Variable erzeugen und übergeben lassen. Oder reden wir einander vorbei? *



OK, also noch mal:

```
public class AdressListe extends Vector
{

Geburtstag geb;

public void adresseEintragen(Geburtstage temp)
{
this.add(temp); //Liste wird hinzugefügt
}

public void adresseAuslesen (){

geb.auslesen(); //Aufruf der Methode aus der Hauptklasse

}
```

Das hier

*Geburtstag geb;*

bedeutet zunächst einmal, dass geb = NULL ist.
Im weiteren Programmablauf rufst Du

*adresseAuslesen()*

auf. In dieser Methode adresseAuslesen() wird jedoch

*geb.auslesen();*

aufgerufen. Und zwar, OHNE dass geb in der Zwischenzeit eine Zuweisung erfahren hat. geb ist also immer noch NULL. Und ein Aufruf auf NULL, nämlich geb.*auslesen()*, verursacht dann die Exception.


----------



## Christian Fein (25. Mai 2004)

Snape hat vollkommen recht.

Falls du es ihm nicht glaubst das die Daten null sind, dann geh vollgenden Weg um zu erfahren, wie jeder Programmierer permanent erfährt, das der Computer immer recht hat:


```
if(geb!=null) {
geb.auslesen(); //Aufruf der Methode aus der Hauptklasse
} else {
 System.out.println("Der Computer hat immer recht!");
}
```


----------



## webix (25. Mai 2004)

Hallo Christian, die geb ist null, jedoch ist die Frage, wie instanziere ich die so, das geb nicht null ist und die übergabe klappt.

Geburtstag geb= new Geburtstag();

klappt nicht.


----------



## Snape (25. Mai 2004)

> _Original geschrieben von webix _
> *Hallo Christian, die geb ist null, jedoch ist die Frage, wie instanziere ich die so, das geb nicht null ist und die übergabe klappt.
> 
> Geburtstag geb= new Geburtstag();
> ...



Siehe PM. Einfach dafür sorgen, dass der fehlende Konstruktor noch implementiert wird.


----------



## webix (25. Mai 2004)

wie schon in pm geschrieben:

public Geburtstag(AdressListe liste)
{
super ("Geburtstag");
this.setSize(600,480);
this.setLayout(null);
this.liste = liste;
}


ist schon vorhanden und bekommt AdressListe übergeben.


----------



## Christian Fein (25. Mai 2004)

Snape hat dir wie er sagt eine mögliche Lösung zugesandt, dann kann ich mich
darauf beschränken, etwas anderes anzumeckern 

Mir wird der Zweck deines Codes nicht so ganz klar.


```
Meine Unterklasse

import java.util.*;
import java.util.Vector.*;
import java.io.*;


public class AdressListe extends Vector
{

Geburtstag geb;

public void adresseEintragen(Geburtstage temp)
{
this.add(temp); //Liste wird hinzugefügt
}

public void adresseAuslesen (){

geb.auslesen(); //Aufruf der Methode aus der Hauptklasse

}
```
Du erweiterst einen Vector der letztendliche eine Instanz einer von Frame abgeleiteten 
Klasse besitzt?

Laut OOP sollte mann Vererbung dann benutzen wenn eine "ist - ein " Beziehung besteht.
Die Frage ist:
Ist ein Geburstag ein Frame? klingt unlogisch.

Auch Instanzvariablen sollten nach dem Prinzip "hat ein" genutzt werden. 
Hat eine AdressenList einen Frame
auch das ist nicht ganz logisch.
Genaus hat bei dir der Geburtstag Frame eine Adressenliste, du hast hier 
also eine 1 - 1 beziehung.

Wenn du diesen Umstand änderst, erreichst du zudem das du keine Klasse erschaffen musst die eine Vorhanden nur unwesentlich erweitert.

Zudem trennst du die Logic nicht von der Ansicht. Das heisst letztendlich baust du den Controller direkt in eine Ansicht ein die hier der GeburtstagFrame ist. 
Besser du hälst dich an MVC und hälst dir einen Controller.

Dieser Controller kann die Ansicht steuern und die Daten (hier adressliste) ändern.
Ich weiss ja nicht was der Geburtstagsframe koennen sollte, aber ich gehe aufgrund
von AdressenList davon aus du willst eine Art Verwaltung von Gästen für eine Geburtstagparty programmieren (veilleicht aus den Fingern gesaugt)


```
public class Party {
   private Vector adressVector;
   private MyView view;
  
  public Party(MyView view) { this.view = view }   

   public void addAdress(Adress adress) {
     adressVector.add(adress);
     view.setAdressList(adressVector);
     view.repaint();
   }
   
....
}
```

Damit hast du deinen Frame komplett von der Adressen Liste entkoppelt und du arbeitest nur mit dem Controller (hier Party) der Zwischen der Ansicht und den Daten vermittelt.

Vorteil ist das du freier bist die Ansicht zu wechseln. Deine Ansicht muss als einzige Vorraussetzung haben MyView zu implementieren (bzw davon abzuleiten).

Ist nur eine Möglichkeit. Das wichtigste ist das du Daten und Ansicht voneinander komplett trennst.


----------



## Snape (25. Mai 2004)

> _Original geschrieben von webix _
> *wie schon in pm geschrieben:
> 
> public Geburtstag(AdressListe liste)
> ...



Siehe PM. Wenn Du

Geburtstag geb= new Geburtstag();

aufrufst, brauchst Du auch den zugehörigen Konstruktor zu new Geburtstag(). Und den habe ich Dir sogar schon geliefert. *fassungslos*.

Für

Geburtstag geb= new Geburtstag();

brauchst Du

public Geburtstag()
{
super ("Geburtstag");
this.setSize(600,480);
this.setLayout(null);
}

während für

public Geburtstag(AdressListe liste)
{
super ("Geburtstag");
this.setSize(600,480);
this.setLayout(null);
this.liste = liste;
}

ein Aufruf dieser Form nötig ist:

AdressListe liste = new AdressListe();
Geburtstag f = new Geburtstag(*liste*);


----------



## Christian Fein (25. Mai 2004)

> _Original geschrieben von webix _
> *wie schon in pm geschrieben:
> 
> public Geburtstag(AdressListe liste)
> ...





```
public class AdressListe extends Vector
    {

    Geburtstag geb;

    public void adresseEintragen(Geburtstage temp)
    {
    this.add(temp); //Liste wird hinzugefügt
    }

    public void adresseAuslesen (){

    geb.auslesen(); //Aufruf der Methode aus der Hauptklasse

    }
```

Hier fehlt der Constructor der dir geb setzt.


----------



## Snape (25. Mai 2004)

> _Original geschrieben von Christian Fein _
> 
> ```
> public class AdressListe extends Vector
> ...



Nun, er könnte auch

```
public class AdressListe extends Vector
{
   Geburtstag geb = new Geburtstag();
//...
}
```
so beginnen.


----------



## Christian Fein (25. Mai 2004)

> _Original geschrieben von Snape _
> *Nun, er könnte auch
> *
> 
> ...



Oder er könnte seine Anwendung umschreiben


----------



## Snape (25. Mai 2004)

> _Original geschrieben von Christian Fein _
> *Oder er könnte seine Anwendung umschreiben  *



Hehe, das wäre in der Tat die beste Lösung. So recht verstanden habe ich auch noch nicht, warum die Vector-Klasse abgeleitet werden muss usw. usw.
Und auch hier sieht man wieder eine unnötige Überladung der main()-Methode...
Interessant auch, dass es in der Klasse Geburtstag einmal eine Instanzvariable AdressListe liste gibt und in main() erneut AdressListe liste = new AdressListe() Verwendung findet... Dieses ganze Geraffel ist konzeptionell für den Eimer...


----------



## webix (25. Mai 2004)

Ok OK Jungs. Danke für Berichtigung und die Tipps


----------

