Java Nullpointer-Exception in Objekt-Array

raffiSSL

Lt. Junior Grade
Registriert
Feb. 2006
Beiträge
289
Hallo, ich sitze an einem Programm das Professuren und deren Lehrveranstaltungen verwalten soll. Dazu habe ich eine Verwaltungsklasse. In dieser wird ein Objekt-Array der Klasse Professur angelegt, und in diesem wiederum ein Objekt-Array von Lehrveranstaltungen (auch eine Klasse).
Jetzt kann ich problemlos Professuren erstellen, die Ausgabe klappt auch fast wunderbar, aber sobald ich auf eine leere Zelle des Professur-Arrays zugreife wirft er mir die Nullpointer-Exception aus. Mir ist klar das dort wo nix von mir eingetragen wurde null steht, aber ist das wirklich der Grund!? Wenn ja wie kann ich das umgehen? Oder habe ich etwas falsch programmiert?

Komisch ist, das er mir zum Beispiel bei der Ausgabe er st die Exception wirft und dann die eingetragenen Professuren wie gewünscht auflistet.

Hier die Verwaltungsklasse (nur mit der Methode anzeigen der Professuren):
Code:
public class Main {

	Professur[] prof;
	Professur testProf;
	SimpleInput in;
	int auswahl; 	//Menü-Auswahl Variable
	int i,z;			//Zählvariable für Schleifen in Methoden
	int zaehl;		//Zählvariable für Professur-Feld
	String profName;
	int profZahl;
	
	public Main () {
		prof = new Professur[50];
		testProf = new Professur();
		auswahl = 0;
		i = z = 0;
		zaehl = 0;
		profZahl = 0;
		in = new SimpleInput();
	}
	
	public void go () {
		
		System.out.println("Was wollen sie tun?");
		System.out.println("1: Professur anlegen");
		System.out.println("2: Lehrveranstaltung anlegen");
		System.out.println("3: Professuren anzeigen");
		System.out.println("4: Lehrveranstaltungen einer Professur anzeigen");
		System.out.println("5: alle Lehrveranstaltungen anzeigen");
		System.out.println("6: Programm beenden");
		System.out.println("===============================================");
		
		do {
			auswahl = in.readInt("Auswahl: ");
			System.out.println();
			switch (auswahl) {
			case 1: 
				prof[zaehl] = testProf.anlegenProf();
				zaehl++;
				break;
			case 2: 
				suche();
				break;
			case 3:
				anzeigeProf();
				break;
			case 4:
				anzeigeFrage();
				break;
			case 5:
				anzeigeLehrundProf();
				break;
			case 6:
				System.out.println("Programm beendet.");
				break;
			default:
				System.out.println("Falsche Eingabe, bitte versuchen Sie es noch einmal.");
				break;
			}
		} while (auswahl != 6 && i < 50);
	}
...
public void anzeigeProf () {
		/*Anzeige der Professurenliste*/
		int help = 0;
		for (i = 0; i < 50; i++) {
			if (prof[i].getName() != null) {
				System.out.println((i+1)+". "+prof[i].getName());
				help++;
			}
		}
		if (help == 0){
			System.out.println("Noch keine Professuren vorhanden");
		}
	}
...

Der Fehler tritt wie gesagt überall auf wo ich das Professurfeld versuche zu durchlaufen.

mfg
 
Du greifst ja hier prof.getName() soweit ich das sehe auf ein Objekt zu, dass ggf. keinen Inhalt (sprich einen Null-Zeiger zurückgibt) hat. Entweder schaust du erst die Größe des Arrays an und begrenzt das ganze dann so, dass du nicht über das Ende des Arrays hinaus auf etwas zugreifst oder du verwendest einen Vektor, der hier wohl besser geeignet wäre.
Hoffe mich nicht zu irren.

Gruß,

badday
 
Mit "prof = new Professur[50];" legst ein Array von Zeigern auf Objekt Professur. Es sind also keine Objekte. Wie badday sagte, es gibt keine Inhalte. Du muss das Array initialisieren. Eine Schleife, in der du jedem Element von prof einen Objekt zuweist.
Etwa so

for (i = 0; i < 50; i++)
prof = new Professur();

Erst wenn Objekte existieren, kannst du auch auf deren Inhalte zugreifen.
 
Also zumindest die Anzeige klappt jetzt ohne Fehlermeldung nachdem ich diese for-Schleife in meine go()-Methode eingebaut habe. Ich habe aber natürlich noch andere Methoden aber dort wird immer diese Nullpointer-Exception geworfen.
Wird das Professur-Array nicht global in der Main-Klasse benutzt und verändert, oder liegt es an etwas ganz anderem?

Mein zweite Frage wäre außerdem noch wo ich diese for-Schleife über das Feld von Objekten in meiner Professurklasse unterbringen soll. In meiner Professurklasse wird wiederum ein Lehrveranstaltungsfeld der maximalen Größe 20 angelegt. Ich habe es bisher nur normal im Kunstruktor initialisiert. Eine go()-Methode hat die Klasse ja nicht, ist es daher egal wo ich die for-Schleife reinpacke?

Hier mal meine komplette Main-Klasse:
Code:
public class Main {

	Professur[] prof;
	Professur testProf;
	SimpleInput in;
	int auswahl; 	//Menü-Auswahl Variable
	int i,z;		//Zählvariablen für Schleifen in Methoden
	int zaehl;		//Zählvariable für Professur-Feld
	String profName;
	int profZahl;
	
	public Main () {
		prof = new Professur[50];
		testProf = new Professur();
		auswahl = 0;
		i = z = 0;
		zaehl = 0;
		profZahl = 0;
		in = new SimpleInput();
	}
	
	public void go () {
		
		for (i = 0; i < 50; i++) {
			prof[i] = new Professur();
		}
		
		System.out.println("Was wollen sie tun?");
		System.out.println("1: Professur anlegen");
		System.out.println("2: Lehrveranstaltung anlegen");
		System.out.println("3: Professuren anzeigen");
		System.out.println("4: Lehrveranstaltungen einer Professur anzeigen");
		System.out.println("5: alle Lehrveranstaltungen anzeigen");
		System.out.println("6: Programm beenden");
		System.out.println("===============================================");
		
		do {
			System.out.println();
			auswahl = in.readInt("Auswahl: ");
			System.out.println();
			switch (auswahl) {
			case 1: 
				prof[zaehl] = testProf.anlegenProf();
				zaehl++;
				break;
			case 2: 
				suche();
				break;
			case 3:
				anzeigeProf();
				break;
			case 4:
				anzeigeFrage();
				break;
			case 5:
				anzeigeLehrundProf();
				break;
			case 6:
				System.out.println("Programm beendet.");
				break;
			default:
				System.out.println("Falsche Eingabe, bitte versuchen Sie es noch einmal.");
				break;
			}
		} while (auswahl != 6);
	}
	
	public void suche () {
		/*Eingabe der Professur, da nur eine Veranstaltung angelegt werden kann, wenn eine verantwortliche Professur existiert
		 *danach Aufruf der Anlegen-Methode oder Ausgabe einer Fehlermeldung
		 */
		profName = in.readString("Name der zuständigen Professur: ");
		int index = sucheProfnachName(profName);
		
		if (index != -1) {
			prof[i].anlegenLehr();
		}
		else {
			System.out.println("Eingbefehler oder Professur nicht vorhanden, daher ist kein Anlegen einer Veranstaltung möglich!");
		}
	}	
		
	public int sucheProfnachName (String profName) {
		/*Suche der Professur nach dem Name, Rückgabe des Index*/
		for (i = 0; i < prof.length; i++) {
			if (prof[i].getName().equals(profName)) {
				return i;
			}
		}
		return -1;
	}
	
	public void anzeigeProf () {
		/*Anzeige der Professurenliste*/
		int help = 0;
		for (i = 0; i < 50; i++) {
			if (prof[i].getName() != null) {
				System.out.println((i+1)+". "+prof[i].getName());
				help++;
			}
		}
		if (help == 0){
			System.out.println("Noch keine Professuren vorhanden");
		}
	}
	
	public void anzeigeFrage() {
		/*Eingabe des Kürzels, danach Aufruf der Such-Methode oder Ausgabe einer Fehlermeldung*/
		String kurz = in.readString("Bitte geben Sie das Professurkürzel ein (die ersten 3 Buchstaben groß geschrieben): ");
		int suchIndex = sucheProfnachKuerzel(kurz);
		if (suchIndex != -1) {
			anzeigeLehr(suchIndex);
		}
		else {
			System.out.println("Professur nicht vorhanden oder Eingabefehler");
		}
	}
	
	public int sucheProfnachKuerzel (String kurz) {
		/*Suche der Professur nach dem Kürzel, Rückgabe des Index*/
		for (i = 0; i < prof.length; i++) {
			if (prof[i].getKuerzel().equals(kurz)) {
				return i;
			}
		}
		return -1;
	}
	
	public void anzeigeLehr (int index) {
		/*Anzeige der Lehrveranstaltungsliste einer Professur*/
		System.out.println("Lehrveranstaltungen der Professur "+prof[index].getName()+":");
		System.out.println();
		for (i = 0; i < prof[index].lehr.length; i++) {
			System.out.println("   - "+prof[index].lehr[i].getVname());
		}
	}
	
	public void anzeigeLehrundProf () {
		/*Anzeige aller Professuren und der dazu gehörigen Lehrveranstaltungen*/
		int help = 0;
		for (i = 0; i < prof.length; i++) {
			for (z = 0; z < prof[i].lehr.length; z++) {
				if (prof[i].getName() != null && prof[i].lehr[z].getVname() != null) {
					System.out.println(prof[i].getName()+":");
					System.out.println("    - "+prof[i].lehr[z].getVname());
					help++;
				}
			}
		}
		if (help == 0) {
			System.out.println("Es sind noch keine Veranstaltungen bzw. Professuren vorhanden");
		}
	}
	
	public static void main (String args[]) {
		Main r = new Main();
		r.go();
	}
}

MfG
 
Zuerst sollte man nicht mit globalen Variablen arbeiten, das hebelt die Idee der objektorientierten Programmierung aus. Variablen sollen als Parameter an Methoden übergeben werden.

Die For-Schleife macht man meistens in Main, gleich nach der Deklarierung der Variablen.

Im Konstruktor müssen alle Variablen initialisiert sein, weiss nicht mehr genau, ob es automatisch gemacht wird. Das könnte eventuell Probleme mit Nullpointer erklären.
 
Warum benutzt du eigentlich ein Array? ArrayList ist meines Erachtens komfortabler.

Bsp.:

Code:
main () {

     List<Professor> profList = new ArrayList<Professor>();

     // 3 Professoren anlegen
     for(int i=0;i < 3;i++) 
         profList.add(new Professor() );

      // anzeigeLehrundProf

      for(Professor prof : profList)
          prof.anzeigeLehrundProf

}

Zusätzlich solltest du dann in deine Klasse Prof noch für Lehrveranstaltung eine ArrayList anlegen.

Guck dir am besten mal das Collection-Framework und Generics an.
 
Ich habe oben schon einmal auf einen Vektor verwiesen, denke das wäre hier optimal.

Gruß,

badday
 
Er sollte ruhig ArrayList nehmen, anstatt Vector. Die beiden Klassen sind sich sehr ähnlich bis auf den Unterschied, dass die Methoden der Klasse Vector synchronisiert sind und die Methoden der Klasse ArrayList nicht. Da dies nur im Zusammenhang mit Threads eine Rolle spielt, ist es genauso gut hier ArrayList zu verwenden.
 
Hallo und danke erstmal für die Antworten. Die Variante mit der ArrayList wäre komfortabler richtig, aber auch hier müsste diese ArrayList doch für die ganze Klasse Main zur Verfügung stehen, um Objekte anzuhängen, zu löschen bzw. zu verändern.

Wieso funktioniert in meiner Main zum Beispiel der Aufruf der Methode anzeigeProf ohne Probleme (dort greife ich doch auch auf prof zu) aber sobald ich den case 2 ausführe und ich den Namen eingegeben habe und die Methode "sucheProfnachName" aufrufe eine Nullpointer-Exception in der zeile wo ich das Professurfeld durchlaufen will?
Normalerweise ist doch das Feld nicht global mit Professurobjekten gefüllt wenn ich dies in der go()-Methode mache oder? Im Kunstruktor wäre es doch besser oder nicht, aber dort eine for-Schleife?

mfg

EDIT: Also ich habe jetzt die Anlegen-Methoden mit in die Main-Klasse geschrieben nun funktioniert das ganze tadellos.

Code:
public class Main {

	Professur[] prof;
	Professur testProf;
	SimpleInput in;
	int auswahl; 	//Menü-Auswahl Variable
	int i,z;		//Zählvariablen für Schleifen in Methoden
	int zaehl;		//Zählvariable für Professur-Feld
	String profName;
	int profZahl;	//Anzahl der bereits angelegten Professuren
	int lehrZahl;	//Anzahl der bereits angelegten Lehrveranstaltungen
	
	public Main () {
		prof = new Professur[50];
		testProf = new Professur();
		auswahl = 0;
		i = z = 0;
		zaehl = 0;
		profZahl = 0;
		lehrZahl = 0;
		in = new SimpleInput();
	}
	
	public void go () {
		
		/*for (i = 0; i < 50; i++) {
			prof[i] = new Professur();
			for (z = 0; z < 20; z++) {
				prof[i].lehr[z] = new Lehrveranstaltung();
			}
		}*/
		
		System.out.println("Was wollen sie tun?");
		System.out.println("1: Professur anlegen");
		System.out.println("2: Lehrveranstaltung anlegen");
		System.out.println("3: Professuren anzeigen");
		System.out.println("4: Lehrveranstaltungen einer Professur anzeigen");
		System.out.println("5: alle Lehrveranstaltungen anzeigen");
		System.out.println("6: Programm beenden");
		System.out.println("===============================================");
		
		do {
			System.out.println();
			auswahl = in.readInt("Auswahl: ");
			System.out.println();
			switch (auswahl) {
			case 1: 
				anlegenProf();
				break;
			case 2: 
				suche();
				break;
			case 3:
				anzeigeProf();
				break;
			case 4:
				anzeigeFrage();
				break;
			case 5:
				anzeigeLehrundProf();
				break;
			case 6:
				System.out.println("Programm beendet.");
				break;
			default:
				System.out.println("Falsche Eingabe, bitte versuchen Sie es noch einmal.");
				break;
			}
		} while (auswahl != 6);
	}
	
	public int anlegenProf () {
		
		if (profZahl < 50) {
			String name = in.readString("Name der Professur: ");
			String dekan = in.readString("Name des Dekans: ");
			String mail = in.readString("E-Mail Adresse: ");
			int mitarbeiterzahl = in.readInt("Anzahl der Mitarbeiter: ");
			String kuerzel = testProf.kuerzelErst(name);
			
			prof[profZahl] = new Professur();
			prof[profZahl].setName(name);
			prof[profZahl].setDekan(dekan);
			prof[profZahl].setMail(mail);
			prof[profZahl].setMitarbeiterzahl(mitarbeiterzahl);
			prof[profZahl].setKuerzel(kuerzel);
			
			return profZahl++;
		}
		else {
			System.out.println("Es können nur 50 Professuren angelegt werden, diese Zahl ist bereits erreicht.");
			return profZahl;
		}
	}
	
	public int anlegenLehr (int index) {
		if (lehrZahl < 20) {
			String vName = in.readString("Veranstaltungsname: ");
			int zeitVorl = in.readInt("Vorlesungsdauer (Minuten/Woche): ");
			int zeitUeb = in.readInt("Uebungsdauer (Minuten/Woche): ");
			
			prof[index].lehr[lehrZahl] = new Lehrveranstaltung();
			prof[index].lehr[lehrZahl].setVname(vName);
			prof[index].lehr[lehrZahl].setZeitBetreutVorl(zeitVorl);
			prof[index].lehr[lehrZahl].setZeitBetreutUeb(zeitUeb);
			
			return lehrZahl++;
		}
		else {
			System.out.println("Die Professur kann nur 20 Veranstaltungen ausrichten, diese Zahl ist bereits erreicht.");
			return lehrZahl;
		}
	}
	
	public void suche () {
		/*Eingabe der Professur, da nur eine Veranstaltung angelegt werden kann, wenn eine verantwortliche Professur existiert
		 *danach Aufruf der Anlegen-Methode oder Ausgabe einer Fehlermeldung
		 */
		profName = in.readString("Name der zuständigen Professur: ");
		int index = sucheProfnachName(profName);
		
		if (index != -1) {
			anlegenLehr(index);
		}
		else {
			System.out.println("Eingbefehler oder Professur nicht vorhanden, daher ist kein Anlegen einer Veranstaltung möglich!");
		}
	}	
		
	public int sucheProfnachName (String profName) {
		/*Suche der Professur nach dem Name, Rückgabe des Index*/
		for (i = 0; i < profZahl; i++) {
			if (prof[i].getName().equals(profName)) {
				return i;
			}
		}
		return -1;
	}
	
	public void anzeigeProf () {
		/*Anzeige der Professurenliste*/
		if (profZahl > 0) {
			for (i = 0; i < profZahl; i++) {
				if (prof[i].getName() != null) {
					System.out.println((i+1)+". "+prof[i].getName());
				}
			}
		}
		else {
			System.out.println("Es sind noch keine Professuren vorhanden.");
		}
	}
	
	public void anzeigeFrage() {
		/*Eingabe des Kürzels, danach Aufruf der Such-Methode oder Ausgabe einer Fehlermeldung*/
		String kurz = in.readString("Bitte geben Sie das Professurkürzel ein (die ersten 3 Buchstaben groß geschrieben): ");
		int suchIndex = sucheProfnachKuerzel(kurz);
		if (suchIndex != -1) {
			anzeigeLehr(suchIndex);
		}
		else {
			System.out.println("Professur nicht vorhanden oder Eingabefehler");
		}
	}
	
	public int sucheProfnachKuerzel (String kurz) {
		/*Suche der Professur nach dem Kürzel, Rückgabe des Index*/
		for (i = 0; i < profZahl; i++) {
			if (prof[i].getKuerzel().equals(kurz)) {
				return i;
			}
		}
		return -1;
	}
	
	public void anzeigeLehr (int index) {
		/*Anzeige der Lehrveranstaltungsliste einer Professur*/
		System.out.println("Lehrveranstaltungen der Professur "+prof[index].getName()+":");
		System.out.println();
		for (i = 0; i < prof[index].lehr.length; i++) {
			if (prof[index].lehr[i].getVname() != null) {
				System.out.println("   - "+prof[index].lehr[i].getVname());
			}
		}
	}
	
	public void anzeigeLehrundProf () {
		/*Anzeige aller Professuren und der dazu gehörigen Lehrveranstaltungen*/
		if (profZahl > 0 && lehrZahl > 0) {
			for (i = 0; i < profZahl; i++) {
				System.out.println(prof[i].getName()+":");
				for (z = 0; z < prof[i].lehr.length; z++) {
					if (prof[i].getName() != null && prof[i].lehr[z].getVname() != null) {
						System.out.println("    - "+prof[i].lehr[z].getVname());
					}
				}
			}
		}
		else {
			System.out.println("Es sind noch keine Veranstaltungen bzw. Professuren vorhanden");
		}
	}
	
	public static void main (String args[]) {
		Main r = new Main();
		r.go();
	}
}

MfG und schönen 1. Advent noch...
 
Zuletzt bearbeitet:
Zurück
Oben