ich beschäftige mich gerade erstmals mit dem Thema "Exceptions" und habe dazu mal folgende Klasse bzw. Methode versucht:
Java:
//Ausgegeben werden soll der größte Eintrag einer als Parameter übergebenen ArrayList.importjava.util.ArrayList;publicclassMaximum{Integermaximum(ArrayList<Integer> a){Integer max=a.get(0);try{for(int i=1; i<a.size(); i++){if( a.get(i)>max ){
max=a.get(i);}}}catch(IndexOutOfBoundsException e){System.out.println("Leeres Array übergeben. Maximum kann nicht bestimmt werden.");}return max;}publicstaticvoidmain(String[] args){Maximum testclass=newMaximum();ArrayList<Integer> b =newArrayList<Integer>();System.out.println(testclass.maximum(b));}}
Ich habe im Rumpf der main-Methode absichtlich keine Elemente in die ArrayList b eingefügt, weil ich ja diesen Fall abfangen möchte; es funktioniert jedoch nicht.
Naja, wenn deine Schleife alle Elemente durchlaufen soll, deine Liste aber keine Elemente hat, kann auch keine Exception geworfen werden... die "kristischen" Stellen werden also eh nie ausgeführt...
Doch Du musst es halt anders programmieren ;-)
Die Exception tritt ausserhalb des des try catch Blocks auf (sollte auch in der Fehlermeldung stehen)
Eine Möglichkeit:
Java:
Integer max =null;try{
max = a.get(0);...
Wobei ich in dem Fall eher die size() der List prüfen und dementsprechend eine eigene Exception werfen würde, anstatt eine IOoBException zu provozieren und deren Ausgabe zu überlagern.
Deswegen frage ich ja, weil bei mir klappt es nur, wenn ich die Variable VOR der Methode selbst deklariere.
Und das verstehe ich nicht.
Erstens müsste das doch auch gehen, wenn ich sie in der Methode (noch vor dem try-Block deklariere) und zweitens sogar, wenn ich sie im try-Block deklariere und initialisiere, weil ich sie doch nur dort brauche.
//Ausgegeben werden soll der größte Eintrag eines als Parameter übergebenen Arrays.importjava.util.ArrayList;publicclassMaximum{Integer max;Integermaximum(ArrayList<Integer> a){try{
max=a.get(0);for(int i=1; i<a.size(); i++){if( a.get(i)>max ){
max=a.get(i);}}}catch(IndexOutOfBoundsException e){System.out.println("Leeres Array: Maximum kann nicht bestimmt werden.");}return max;}publicstaticvoidmain(String[] args){Maximum testclass=newMaximum();ArrayList<Integer> b =newArrayList<Integer>();System.out.println(testclass.maximum(b));}}
Du willst doch auf dein max auch beim return zugreifen, d.h. du könntest es bestenfalls noch lokal in der Methode deklarieren, anstelle von klassenweit.
classMaximum{Integermaximum(ArrayList<Integer> a){Integer max =null;try{
max=a.get(0);for(int i=1; i<a.size(); i++){if( a.get(i)>max ){max=a.get(i);}}}catch(IndexOutOfBoundsException e){System.out.println("Leeres Array: Maximum kann nicht bestimmt werden.");}return max;}}
Also bei mir läuft´s... hab aber auch noch ´ne Klammer hinzugefügt.
EDIT: Ich erinnere dich an dieser Stelle nochmal an einen vorigen Beitrag:
Wobei ich in dem Fall eher die size() der List prüfen und dementsprechend eine eigene Exception werfen würde, anstatt eine IOoBException zu provozieren und deren Ausgabe zu überlagern.
Initialisieren macht man nur einmal... darum heißt es auch INITialisieren. Das, was du mit
Code:
max = a.get(0)
machst, ist eine stinknormale Zuweisung (= null ist auch nichts anderes, da du´s aber das erste mal machst, spricht man von der erstmaligen Zuweisung - der Initialisierung).
EDIT: Du kannst aber auch einfach deine Variable trotzdem im try-Block deklarieren und nach dem Abarbeiten der Schleife return max verwenden. Unter den cath-Block schreibst du dann return null.
Es wird zeit, dass ich irgendwie die Prüfung schaffe, dann zwei bis 5 Kreuze in den Kalender mache und mich dann demütig vom Javabereich entferne... :autsch:
O je, es kompiliert, aber bitte nicht nachmachen! :shock:
Java:
int max =maximum(newArrayList<Integer>());// schöne NullPointerException
Code:
IndexOutOfBoundsException
ist ein Laufzeitfehler. Nicht abfangen!
Mit
Code:
int
, nicht mit
Code:
Integer
rechnen!
Dass der Compilerfehler angezeigt wurde, hatte auch einen guten semantischen Grund. Wenn man den Fehler abfängt, kann man nichts Sinnvolles zurückgeben.
Variablen sind nur in dem Block sichtbar, in dem sie deklariert wurden.
importjava.util.ArrayList;publicclassMaxInt{publicstaticvoidmain(finalString[] args){finalint max =maximum(newArrayList<Integer>());}staticIntegermaximum(finalArrayList<Integer> a){Integer max =null;try{
max = a.get(0);for(int i =1; i < a.size(); i++){if(a.get(i)> max){
max = a.get(i);}}}catch(finalIndexOutOfBoundsException e){
e.printStackTrace();}return max;}}
Oder kürzer:
Java:
publicstaticvoidmain(finalString[] args){Integer i =null;int j = i;}
Java versucht, aus der
Code:
null
den primitiven Wert zu ziehen, was natürlich nicht funktioniert.
staticintmaximum(finalArrayList<Integer> a){if(a.isEmpty()){thrownewIllegalArgumentException("Liste darf nicht leer sein!");}int max = a.get(0);for(int i =1; i < a.size(); i++){if(a.get(i)> max){
max = a.get(i);}}return max;}
Ich habe noch ein paar Verbesserungen vorgenommen.
Könnt Ihr mir bitte sagen, ob folgender Code okay ist bzw. ob er eine Alternative zu dem obigen Krams mit catch und try ist?
Ich habe ein paar Beispiele ausprobiert (leere Liste und verschiedene gefüllte Listen) und bei mir funktioniert es; dennoch interessiert mich Eure Meinung.
Java:
importjava.util.ArrayList;classMaximum{Integermaximum(ArrayList<Integer> a ){Integer max;if( a.isEmpty()){
max =null;return max;}
max = a.get(0);for(int i =1; i < a.size(); i++){if( a.get(i)> max ){
max = a.get(i);}return max;}publicstaticvoidmain(String[] args){ArrayList<Integer> testArrayList =newArrayList<Integer>();Maximum testClass =newMaximum();
testArrayList.add(1);
testArrayList.add(200);
testArrayList.add(5);
testArrayList.add(50);System.out.println( testClass.maximum( testArrayList ));}}
Bei diesem Beispiel wird bei mir auf der Konsole 200 ausgegeben.
Wenn ich in die Liste
Du solltest nur wahrscheinlich statt Integer mal int verwenden... ansonsten fällt mir nichts ein (abgesehen von der unerhebl,ichen Kleinigkeit, dass wohl niemand eine Klasse Maximum nennt und dann auch noch nie einzige Funktion).
Achja, eine Sache noch: wenn man schon das Interface Iterable irgendwann implementiert (z.B. mittels einer Collection wie ArrayList), dann durchlaufe die auch mal mit dem gelieferten Iterator... dafür is er da
Achja, eine Sache noch: wenn man schon das Interface Iterable irgendwann implementiert (z.B. mittels einer Collection wie ArrayList), dann durchlaufe die auch mal mit dem gelieferten Iterator... dafür is er da
, mit welchem du sukzessive jedes Element durchlaufen kannst.
In deinem Fall ist es eher irrelevant, ob du mittels for-Schleife oder Iterator durch die Elemente gehst, aber so machem Benutzer der ersten Variante soll in ähnlichen Anwendungsfällen bereits eine sog
Code:
CurrentModificationException
um die Ohren geflogen sein, deren Ursachenfindung immer ein bisschen hakelig ist...