ich unternehme gerade meine ersten Gehversuche mit Java und komme bei
folgendem Problem nicht weiter.
Aus einer Datei sollen Daten zeilenweise eingelesen und in einem
Stringarray gespeichert werden. Die geschieht mit folgendem Code (gekürzt!)
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
//import java.util.Arrays;
import java.util.ArrayList;
public class Test extends GlgJBean implements ActionListener
{
String[] strDaten = new String[9];
public Test()
{
}
// Werte aus Datei einlesen
strDaten = ReadFile();
String[] ReadFile() //Fehlerstelle
{
try
{
final FileInputStream fin = new FileInputStream("data.pvd");
InputStreamReader isr = new InputStreamReader( fin );
BufferedReader defBufferedReader = new BufferedReader( isr );
ArrayList<String> daten = new ArrayList<String>();
String readLine = null;
while ((readLine = defBufferedReader.readLine()) != null)
{
daten.add(readLine);
}
defBufferedReader.close();
isr.close();
fin.close();
return (String[])daten.toArray();
} catch (Exception e)
{
}
}
}
An der Position //Fehlerstelle sagt mir Eclipse "This method must return
a result of type String[]".
Ich kann diese Fehlermeldung nicht deuten. Mit Hilfe von Google habe ich
zwar noch einige Fehler in der Methode beseitigen können, aber hier ist
Ende.
Der Rückgabewert der Methode ist doch vom Typ String[]!
Wo liegt der Fehler?
MfG Peter
Stefan Kuhne
> return (String[])daten.toArray();
>
> } catch (Exception e)
>
> An der Position //Fehlerstelle sagt mir Eclipse "This method must return
> a result of type String[]".
Das Problem ist, dass im Fall einer Exception kein Rückgabewert erzeugt
wird. Im Prinzip muss der auch nicht erzeugt werden weil er im
Fehlerfall nicht abgefragt werden kann - warum Eclipse da jammert weiss
ich auch nicht (entweder Nachlässigkeit von Eclipse oder es steht
irgendwo in Java-Spec).
Löse es einfach so:
String strDat[]=null;
try {
...
strDat = (String[])daten.toArray();
} catch (Exception e) {
}
return strDat;
Allerdings hat Dein Code noch einen Fehler: Der FileInputStream wird nur
geschlossen, wenn der Code sauber durchgelaufen ist. Im Fehlerfall
bleibt aber das Handle dumm herumstehen (kann sehr lästig werden).
Also so:
Löse es einfach so (gleichzeitig auch eine andere Variante den
Rückgabewert zu erzeugen):
FileInputStream fin = null;
try {
fin = new FileInputStream("data.pvd");
...
return (String[])daten.toArray();
} catch (Exception e) {
return null;
} finally {
if (fin != null) try { fin.close(); } catch (IOException e) {}
}
Für den ganzen close-Schabernak und seine möglichen Exceptions bietet
sich übrigens ein Helper irgendwo in der Toolbox an:
public class Helper
public static void close(Object o) {
if (o == null) return;
try {
if (o instanceof InputStream) (Inputstream o).close();
if (o instanceof OutputStream) (OutputStream) o).close();
// etc..
} catch (Throwable t) {
// ignore
}
}
Bernd
--
Visit http://www.nixwill.de and http://www.spammichvoll.de
jean....@nixwill.de & bernado....@spammichvoll.de
> 2. Warum unbedingt ein [] und nicht die ArrayList?
Wie gesagt, sind das meine ersten Begegnungen mit Java. Ich lehne mich
dabei an Beispielen aus Büchern und dem Netz an. Ist kein Muß!
> 3. Kann man so einen Typcast "(String[])" machen?
Ich denke schon.
MfG Peter
Kann es aber nicht. Das ist der Fehler, den Eclipse bemängelt. Es fehlt
für den Fall der Exception ein return (vom Typ String[]).
Bye
Achim
Vielen Dank! Ich habs kapiert.
MfG Peter
> Das Problem ist, dass im Fall einer Exception kein Rückgabewert
> erzeugt wird. Im Prinzip muss der auch nicht erzeugt werden weil er im
> Fehlerfall nicht abgefragt werden kann - warum Eclipse da jammert
> weiss ich auch nicht (entweder Nachlässigkeit von Eclipse oder es
> steht irgendwo in Java-Spec).
Die Ausnahme wird geschluckt, dadurch wird der Rückgabewert im (nicht
nach außen sichtbaren) Fehlerfall durchaus gebraucht.
>> 2. Warum unbedingt ein [] und nicht die ArrayList?
> Wie gesagt, sind das meine ersten Begegnungen mit Java. Ich lehne mich
> dabei an Beispielen aus Büchern und dem Netz an. Ist kein Muß!
>
>> 3. Kann man so einen Typcast "(String[])" machen?
> Ich denke schon.
Offenbar geht der Typecast nicht so ohne weiteres. Hab Deinen Hinweis
befolgt und arbeite jetzt mit einer ArrayList.
Damit funktioniert es.
Danke und Gruß
Peter
Du hast natürlich vollkommen recht, hatte da Ketchup auf den Augen ;-)
Natürlich funktioniert der Typecast völlig problemlos.
> Das Problem ist, dass im Fall einer Exception kein Rückgabewert erzeugt
> wird. Im Prinzip muss der auch nicht erzeugt werden weil er im
> Fehlerfall nicht abgefragt werden kann - warum Eclipse da jammert weiss
> ich auch nicht (entweder Nachlässigkeit von Eclipse oder es steht
> irgendwo in Java-Spec).
Nein. Der Compiler jammert völlig zu Recht. Denn die Exception wird
innerhalb der Methode abgefangen und behandelt. Und damit terminiert die
Methode auch im Fall der Exception nicht abrupt, sondern normal und muss
demnach auch einen gültigen Rückgabewert liefern.
Gruß,
Michael
> Für den ganzen close-Schabernak und seine möglichen Exceptions bietet
> sich übrigens ein Helper irgendwo in der Toolbox an:
>
> public class Helper
> public static void close(Object o) {
> if (o == null) return;
> try {
> if (o instanceof InputStream) (Inputstream o).close();
> if (o instanceof OutputStream) (OutputStream) o).close();
> // etc..
> } catch (Throwable t) {
> // ignore
> }
> }
Oder besser gleich so:
public static void close(Closeable closable)
{
if (closable == null) {
return;
}
try {
closable.close();
} catch (Throwable t) {
// ignore
}
}
In dieser Form funktioniert das seit Java 1.5. Wer Support für ältere
Versionen benötigt, kommt um deine oder eine ähnliche Version wohl nicht
umhin.
Das fangen von java.lang.Throwable ist diskussionswürdig. Hier wäre
java.lang.Exception wohl deutlich angebrachter. Du möchtest VM-Errors
nämlich ziemlich sicher nicht einfach wegwerfen.
Tobias
>> if (o instanceof OutputStream) (OutputStream) o).close();
> public static void close(Closeable closable)
Vorsicht, bei InputStreams kann man die Exceptions beim Close sicherlich
problemlos ignorieren, beim Schreiben kann dies aber zu unbemerktem
Datenverlust führen.
> Das fangen von java.lang.Throwable ist diskussionswürdig. Hier wäre
> java.lang.Exception wohl deutlich angebrachter. Du möchtest VM-Errors
> nämlich ziemlich sicher nicht einfach wegwerfen.
Oder diese explizit fangen und weiterwerfen (notfalls).
Gruss
Bernd
> Das fangen von java.lang.Throwable ist diskussionswürdig. Hier wäre
> java.lang.Exception wohl deutlich angebrachter. Du möchtest VM-Errors
> nämlich ziemlich sicher nicht einfach wegwerfen.
Theoretisch nein, in der Praxis schon weil mir ein VM-Fehler beim Close
(und die gab es immer mal wieder) togal ist.
> > Das fangen von java.lang.Throwable ist diskussionswürdig. Hier wäre
> > java.lang.Exception wohl deutlich angebrachter. Du möchtest VM-Errors
> > nämlich ziemlich sicher nicht einfach wegwerfen.
>
> Theoretisch nein, in der Praxis schon weil mir ein VM-Fehler beim Close
> (und die gab es immer mal wieder) togal ist.
In der Praxis ist es so, dass man Errors bis auf wenige Ausnahmen *immer*
weiter leiten und nichts weiter unternehmen sollte (abgesehen vom Finally-
Block, aber der wird ja sowieso ausgeführt). Die wohl bekannteste Ausnahme
ist der AssertionFailedError, wobei ich es hier für einen Design-Fehler
seitens Sun hallte, dass das ein Error und keine RuntimeException ist.
Gruss,
Raffi
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is *nothing* like Shakespeare!
her...@raffael.ch · PGP Key 5D1FF5F4 · http://www.raffael.ch/
>> Theoretisch nein, in der Praxis schon weil mir ein VM-Fehler beim Close
>> (und die gab es immer mal wieder) togal ist.
>
> In der Praxis ist es so, dass man Errors bis auf wenige Ausnahmen *immer*
> weiter leiten und nichts weiter unternehmen sollte
Also wenn ich bei IO Operationen irgendeinen Fehler habe (und wenn er
aus der VM kommt) versuch ich trotzdem noch das rettende .close() zu
erreichen und werf den Fehler ggf. neu.
Irgendwelche Phantomhandles herumliegen zu haben halte ich für mehr als
lästig, so manche VM räumt nicht vernünftig auf.
> Also wenn ich bei IO Operationen irgendeinen Fehler habe (und wenn er
> aus der VM kommt) versuch ich trotzdem noch das rettende .close() zu
> erreichen und werf den Fehler ggf. neu.
Yep, das versuchen wir ja im Finally-Block ... ich denke, wir sind uns
eigentlich einig. Ich bin halt der Meinung, dass man Errors bis zum
bitteren Ende durchschlagen lassen sollte, ggf. kann man noch einen Versuch
unternehmen, dieses Ereignis in ein Log zu schreiben.
> Irgendwelche Phantomhandles herumliegen zu haben halte ich für mehr als
> lästig, so manche VM räumt nicht vernünftig auf.
Die werden im Finally-Block ja noch aufzuräumen versucht, Error hin oder
her. Wenn es dumm läuft, erzeugen wir einen neuen Error, der den
ursprünglichen überdeckt, ausser, wir verschlucken alles, was der Versuch,
aufzuräumen, an weiteren Errors verursachen könnte -- in dieser Beziehung
hast du mich durchaus zum Denken angeregt ...
Aber eigentlich sind das derart katastrophale Situationen, dass gleich die
gesamte VM beendet werden müsste. Wenn dann noch Handles offen bleiben,
sollte man sich darüber Gedanken machen, sich ein brauchbares OS zu
organisieren ... :)
So wie andere schon erklärt haben. Einfacher geht auch:
(...)
{
try
{
(...)
return (String[])daten.toArray();
} catch (Exception e) {
return null;
}
}
Mfg
Janusch
http://kathorncity.no-ip.info/de