# Exception in thread "main"



## Sund0se (27. Jun 2010)

Hi Leute
Wir programmieren ca. seit 2 Monaten in der Schule Java. Nun hab ich mich an ein kleines Programm, dass Bankkonten verwalten soll gewagt. Man kann beliebig viel Konten erstellen und anschließend beliebig viel Bakomatkarten verwalten. Wie gesagt bin ich noch Anfänger und ich habe noch nicht viel Programmiert in Java. 

Wenn ich ein Konto anlege geht noch alles. Ich kann auch beliebig viele Bankomatkarten zu diesem Konto anlegen. Doch wenn ich 2 oder 3 Konten anlege, kommt eine Fehlermeldung, die so lautet: 

```
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
	at Girokonto.addBankomatkarte(Girokonto.java:31)
	at Verwalten.main(Verwalten.java:25)
"
```
Da ich mich bei Fehlermeldungen null auskenne und ich den Fehler nicht finde, wollt ich euch um Rat bitten.

Hier der Code: 

Verwalten.java

```
/* Hier kann man mit einer Bank einen Vertrag abschließen, */
/* und anschließend Konten und Bankomatkarten erzeugen 	   */
public class Verwalten {
	public static void main(String[] args) {
		Bank Raika = new Bank("Raiffeisenbank", "Micheldorf", "Regina KLAUSRIEGLER", 34318, 2);
		Girokonto k1 = new Girokonto(3, 2500);
		//Girokonto k2 = new Girokonto(1, 5000);
		Bankomatkarte b1 = new Bankomatkarte();
		Bankomatkarte b2 = new Bankomatkarte();
		Bankomatkarte b3 = new Bankomatkarte();
		Raika.addKonto(k1);
		//Raika.addKonto(k2);
		k1.addBankomatkarte(b1);
		k1.addBankomatkarte(b2);
		k1.addBankomatkarte(b3);
		//k2.addBankomatkarte(b3);
		
		System.out.println(Raika);
		k1.zahleEin(3000);
		System.out.println("\n\n----------------------------------\n\n");
		System.out.println(Raika);
	}
}
```

Bank.java

```
public class Bank {						
	private String nameBank;			// Name der Bank
	private String berater;				// Name des Beraters
	private String standortBank;		// Bankleitzahl
	private int blz;					// Bankleitzahl
	private Konto[] konten;				// Mehrere Konten pro Bank
	private int anzahlKonten;			// Anzahl der konten pro Bank
	private static int zaehler = 0;		// Fuer das erzeugen von Kontos

	/* Konstruktor */
	public Bank(String nameBank, String standortBank, String berater, int blz, int anzahlKonten) {
		this.nameBank = nameBank;
		this.berater = berater;
		this.standortBank = standortBank;
		this.blz = blz;
		this.anzahlKonten = anzahlKonten;
		System.out.println("Sie haben so eben einen Vertrag mit der Bank " +
				nameBank + " in " + standortBank + " abgeschlossen.\nWenn Sie Fragen, " +
				"Probleme ect. haben wenden Sie sich an ihre(n) persönlichen Berater(in) " + 
				berater + ".\nDie Bankleitzahl lautet " + blz + ".\n\n\n");
		if(!genugAnzahl())
			konten = new Konto[anzahlKonten];			// So viele Konten anlegen wie anzahlKonten (Speicher reservieren)
		else
			konten = new Konto[1];						// Ein Konto anlegen (Speicher reservieren)
	}
	
	// Ermittelt ob man mindestens ein Konto anlegen will
	private boolean genugAnzahl() {
		if(anzahlKonten <= 0)
			return true;
		else
			return false;
	}
	
	public void addKonto(Konto k) {
		konten[zaehler++] = k;
	}
	/* Diese Methode gibt die wichtigsten Attribute der Bank aus */
	public String toString() {
		String ausgabe = "\tInfos zur Bank:\n";
		ausgabe += "Name der Bank: " + nameBank + "\nBerater: " + berater + "\nStandort der Bank: " + standortBank +
			"\nBankleitzahl" + blz + "\nAnzahl der Konten: " + anzahlKonten;
		ausgabe += "\n\n\n";
		for(int i=0;i<zaehler;i++) {
			ausgabe += "\n\n\nKonto " + (i+1) + ":\n";
			ausgabe += ausgabe + konten[i];
		}
		return ausgabe;
	}
}
```

Konto.java

```
/* Superklasse Konto	*/
public class Konto {									// Konto erbt die Attribute und Methoden von Bank
	/* Instanzvariablen */
	private double saldo = 0.0;							// Geld auf dem Konto in Euro
	private int kontonr;								// Kontonummer, Bei jedem Konto anders
	/* Klassenvariablen */
	private static int zaehler = 00000055475;			// zeahler braucht man, damit jedes Konto eine andere Kontonummer hat
	
	/* Konstruktor */
	public Konto(double saldo) {						// Parameter: saldo: das Sie beim anlegen eines Kontos einzahlen wollen
		this.saldo = saldo;
		kontonr = zaehler++;							// Kontonummer = Zaehler; Zaehler + 1; (Jedes Konto andere kontonr)
	}
	
	/* Methoden */
	// Zahle bestimmten Betrag in das Konto ein
	public void zahleEin(double betrag) {
		saldo += betrag;							// Ihr Saldo vergroeßert sich
	}
	// Zahle bestimmten Betrag aus (ueberweisen z.B.)
	public void zahleAus(double betrag) {
		saldo -= betrag;							// Ihr Saldo verkleinert sich
	}
	// Um Saldo fuer Girokonto zu verwenden
	public double getSaldo() {	
		return saldo;
	}
	// Um Kontonummer fuer Girkonto zu verwenden
	public int getKontonr() {
		return kontonr;
	}
	
}
```

Girokonto.java

```
/* Subklasse Girokonto	*/
public class Girokonto extends Konto {								// Girokonto erbt die Attribute und Methoden von Konto
	/* Instanzvariablen */
	private int anzahlKarten;										// Anzahl der Bankomatkarten fuer dieses Girokonto
	private Bankomatkarte[] bankomatkarten;							// Referenz auf Bankomatkarte, damit man mehrere Bankomatkarten pro Konto haben kann
	private double saldo = getSaldo();								// Geld auf dem Konto
	private static final double zinssatz = 3;						// Zinssatz
	/* Klassenvariablen */
	private static final double rahmen = -2000;						// Ueberziehungsrahmen in Euro, bei allen Konten gleich (static) und nicht veraenderbar (final)	
	private static int zaehler = 0;									// Wird zumum hinzufuegen von Bankomatkarten verwendet
	
	public Girokonto(int anzahlKarten, double saldo) {
		super(saldo);
		this.anzahlKarten = anzahlKarten;
		if(!genugAnzahl())											// Wenn man min. eine Bankomatkarte anlegen will...
			bankomatkarten = new Bankomatkarte[anzahlKarten];		// ...anzahlKarten Bankomatkarten anlegen
		else 														// Sonst...
			bankomatkarten = new Bankomatkarte[1];					// ... EINE Bankomatkarte anlegen
	}
	// Ermittelt ob man mindestens eine Bankomatkarte anlegen will
	private boolean genugAnzahl() {
		if(anzahlKarten <= 0)
			return true;
		else
			return false;
	}
	
	/* Diese Methode fuegt eine Bankomatkarte zu einem Girokonto hinzu */
	public void addBankomatkarte(Bankomatkarte bK) {
		bankomatkarten[zaehler++] = bK;								// Bankomatkarte hinzufuegen und den Zaehler erhoehen
	}
	
	public void zahleEin(double betrag) {
		super.zahleEin(betrag);										// Methode zahleEin(double) der Superklasse aufrufen
	}
	public void zahleAus(double betrag) {
		if(rahmenUeberschritten(betrag))							// Wenn der Rahmen ueberschritten wurde...
			System.out.println("Keine Auszahlung möglich, da der Rahmen überschritten wurde!");			// ... keine Auszahlung moeglich
		else														// Wenn der Rahmen nicht ueberschritten wurde....
			super.zahleAus(betrag);									// ... Methode zahleAus(double) der Superklasse aufrufen
	}
	/* Diese Methode prueft, ob der Rahmen ueberschritten wurde */
	public boolean rahmenUeberschritten(double betrag) {
		if(saldo - betrag <= saldo)
			return true;
		else
			return false;
	}
	
	/* Diese Methode gibt die wichtigsten Attribute des Girokontos aus */
	public String toString() {
		String ausgabe = "\tInfos zu diesem Konto:\n";
		ausgabe += "Kontonummer: " + super.getKontonr() + "\nSaldo: " + super.getSaldo() + "\nZinssatz: " + zinssatz + " Prozent"
			+ "\nAnzahl der Bankomatkarten: " + anzahlKarten + "\nÜberziehungsrahmen: " + rahmen;
		ausgabe += "\n\n\n";
		for(int i=0;i<zaehler;i++) {
			ausgabe += "\n\nBankomatkarte " + (i+1) + ":\n";
			ausgabe += ausgabe + bankomatkarten[i];
		}
		return ausgabe;
	}
}
```

Bankomatkarte.java

```
public class Bankomatkarte {		// Bankomatkarte erbt die Attribute und Methoden von Girokonto
	private int nummer;								// Jede Bankomatkarte hat eine eindeutige Nummer
	private static int limit = 200;					// Limit in Euro, wie viel man auf einmal abheben darf
	private static int zaehler = 1234567;			// Wir fuer das vergeben von Nummern verwendet
	/* Konstruktor */
	public Bankomatkarte() {
		nummer = zaehler++;		// Vergibt jeder Bankomatkarte eine eindeutige Nummer
	}
	
	/* Diese Methode gibt die wichtigsten Attribute der Bankomatkarte aus */
	public String toString() {	
		String ausgabe = "\tInfos zu dieser Bankomatkarte:\n";
		ausgabe += "\nNr.: " + nummer + " Limit: " + limit;
		return ausgabe;
	}
}
```

Für Verbesserungsvorschläge bin ich natürlich auch dankbar.

lg sund0se


----------



## SlaterB (27. Jun 2010)

die Fehlermeldung besagt, dass du einen falschen Arrayzugriff hast, Index 3 welcher zu hoch oder zu klein ist

wie man das schon nicht verstehen oder nachschlagen kann, ist schwerer als der Fehler selber,
und der Rest ist eigentlich leicht, aber bevor Nachfragen kommen:

aus dem StackTrace kann man auch die genaue Klasse + Zeilennummer der Fehlermeldung erkennen,
> bankomatkarten[zaehler++] = bK; 
dass du ein Array der Größe 3 hast und dreimal was hinzufügst ist schnell erkannt bzw. weißt du sicher selber,
erlaubte Indexe bei einem 3er Array sind 0, 1, 2, 
aus irgendeinem Grund wird mit Index 3 zugegriffen

ganz gewiss liegt das an diesem unmöglichen zaehler++-Konstrukt im Array-Zugriff,
selbst nach 20.000 Posts würde ich das nie schreiben (wenn nicht gerade in 50 Zeilen hintereinander um Platz zu sparen, schwer getestet)
wie kommt man nur auf solche Schreibweisen?

was auch immer du da haben möchtest (erst zaehler erhöhen, dann Array-Zugriff oder andersrum),
schreib es doch ganz eindeutig leserlich ohne Missverständnisse oder eben Bugs wie diesen hier

entweder
bankomatkarten[zaehler] = bK; 
zaehler++;

oder
zaehler++;
bankomatkarten[zaehler] = bK;

edit:
ok, das mit dem static ist der Grund, das andere fand ich nerviger


----------



## Michael... (27. Jun 2010)

Sund0se hat gesagt.:


> ```
> "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
> at Girokonto.addBankomatkarte(Girokonto.java:31)"
> ```


Das entscheidende steht in den ersten zwei Zeilen:
Zeile 1: es wird versucht auf einen nicht existierenden Index (Index 3) eines Arrays zu zugreifen.
Zeile 2: und zwar innerhalb der Methode addBankomatkarte() der Klasse Girokonto, genauer in Zeile 31 der Klasse Girokonto
Die Ursache ist, dass die Variable zaehler in der Klasse Variable statisch definiert ist, das heisst alle Objekte dieser Klasse teilen sich diese Variable, d.h. sobald drei Bankomatkarten zu beliebigen Girokonten hinzugefügt wurden ist Schluss. Auch wenn einzelnen Girokonten noch keine bzw. weniger als 3 Karten zugewiesen wurden.


----------



## Sund0se (27. Jun 2010)

Habs verstanden, vielen dank!


----------

