Hallo,
dies ist mein erster Beitrag in diesem Forum. Ich bin zurzeit dabei, mir die Java-Grundlagen anzueignen. Beim lernen/üben ist mir heute aufgefallen, das ich einen Fehler bekomme, wenn ich den für die do-while-Schleife verwendeten Integer nicht initialisiere. Dies scheint früher aber wohl so funktioniert zu haben?! Ich bin mir aber dessen bewusst, das man eine Variable immer initialisieren sollte ^^
Es werden nur Klassen und Instanzvariablen mit einem Standardwert initialisiert.
Lokale Variablen müssen immer manuell initialisiert werden. Ist wohl eine Designentscheidung. Aus der Spezifikation:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created
[...]
A local variable must be explicitly given a value before it is used, by either initialization or assignment, in a way that can be verified by the compiler using the rules for definite assignment.
importjava.util.Scanner;publicclassSchleifeDo{publicstaticvoidmain(String[] args){Scanner leser =newScanner(System.in);int anzahl =0;do{System.out.print("Anzahl eingeben, min. 1, max 10: ");String eingabe = leser.nextLine();switch(eingabe){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"10":
anzahl =Integer.parseInt(eingabe);break;default:System.out.println("Falsche Eingabe, bitte erneut versuchen");}}while(anzahl<1|| anzahl>10);
leser.close();System.out.printf("Anzahl: %d%n", anzahl);}}
So funktioniert er nicht:
Java:
importjava.util.Scanner;publicclassSchleifeDo{publicstaticvoidmain(String[] args){Scanner leser =newScanner(System.in);int anzahl;do{System.out.print("Anzahl eingeben, min. 1, max 10: ");String eingabe = leser.nextLine();switch(eingabe){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case"10":
anzahl =Integer.parseInt(eingabe);break;default:System.out.println("Falsche Eingabe, bitte erneut versuchen");}}while(anzahl<1|| anzahl>10);
leser.close();System.out.printf("Anzahl: %d%n", anzahl);}}
Fehlermeldung:
Java:
Exception in thread "main" java.lang.Error:Unresolved compilation problems:The local variable anzahl may not have been initialized
The local variable anzahl may not have been initialized
The local variable anzahl may not have been initialized
at SchleifeDo.main(SchleifeDo.java:31)
Wobei es ja hier ohne die Initialisierung keine Probleme gibt:
Java:
int whatever;String schsch ="5";
whatever =Integer.parseInt(schsch);
Naja im letzten Beispiel, initialisierst du den Wert ja auch mit whatever =Integer.parseInt(schsch);. Da spielt es keine Rolle ob er vorher anders initialisiert war oder nicht.
Dein zweites Beispiel funktioniert nicht, weil lokale Variablen per Definition manuell initialisiert werden müssen bevor sie genutzt werden können. Angenommen du würdest die Zahl 15 eingeben, dann würdest du in den default-Teil deiner switch-case Anweisung kommen.
anzahl wäre also immer noch nicht initialisiert und danach würdest du aber versuchen die Abbruchbedingung der while-Schleife aufzuwerden, was nicht funktionieren kann, weil anzahl garnicht initialisiert ist. Deswegen kompiliert das ganze erst garnicht. anzahl hat eben auch keinen Standardwert 0 oder irgendwas.
Wenn du im default-Teil sagen würdest:
anzahl=irgendwas, dann wäre der Compiler wohl schlau genug zu erkennen, dass anzahl vor dem Prüfen der while-Bedingung initialisiert ist. a hat eben auch keinen Standardwert 0 oder irgendwas.
Okay, soweit klar. Aber von einer Initialisierung spricht man doch eigentlich nur, wenn eine Zuweisung direkt in der Deklaration erfolgt? Sollte man dementsprechend auch Stringvariablen immer erst mit null initialisieren, oder ist dass hier überflüssig, weil dies automatisch geschieht?
In Deinem Beispiel MUSST Du es sogar, sonst wäre der String ja beim anschließenden 'parseInt' nicht initialisiert und es flöge wieder eine Exception !!
Im Grunde vergleichst Du aber Äpfel mit Birnen ...
Es werden nur Klassen und Instanzvaraiblen (welche keine Primitiven sind) automatisch auf null gesetzt.
Java:
publicclassTest{String s1;//wird automatisch mit null initialisiertpublicvoidprintInstanceVariable(){System.out.println(s1);//funktioniert, da s1 eine Instanzvariable ist, die automatisch initialisiert wird}publicvoidprintLocalVariable(){String s2;//lokale Variablen werden nicht automatisch initialisiertSystem.out.println(s2);//kompiliert nicht, da s2 nicht initialisiert ist.}}
Das hatte ich vorhin genau so gelesen, deswegen die Frage ^^ http://www.c-howto.de/tutorial-variablen-deklaration.html
Wobei ich auf diese Seite nur zufällig beim Googlen gestoßen bin.
Diese ist normalerweise keine meiner Quellen.
In Deinem Beispiel MUSST Du es sogar, sonst wäre der String ja beim anschließenden 'parseInt' nicht initialisiert und es flöge wieder eine Exception !!
Im Grunde vergleichst Du aber Äpfel mit Birnen ...
Nur mal so als Tipp: wenn Du in Java programmieren willst, dann sollst Du keine C-Tuts lesen (oder aber eine entsprechende Transferleistung bringen)
Gruß Klaus
Nur mal so als Tipp: wenn Du in Java programmieren willst, dann sollst Du keine C-Tuts lesen (oder aber eine entsprechende Transferleistung bringen)
Gruß Klaus