ich habe ein Package mit mehreren Klassen, die mitunter die selben Exceptions werfen können.
Manche Exceptions sollen public sein, andere werden nur innerhalb des Packages verwendet.
Wo deklariert man die Exceptions am besten? Muss ich jede einzelne Exception tatsächlich in ein eigenes File stecken (sonst meckert nämlich mein Compiler bzw. die NetBeans-IDE)?
Wenn ich zB. die Exceptions so deklariere:
Code:
public class Oberklasse {
...
public class Exception1 extends Exception{
...
}
public class Exception2 extends Exception{
...
}
}
kann ich leider nicht wie gewünscht darauf zugreifen:
Code:
public class AndereKlasse {
...
public void macheIrgendEtwas {
...
throw new Oberklasse.Exception1();
}
}
meckert er: An enclosing instance that contains Oberklasse.Exception1 is required!
Du könntest die Exceptionklassen static machen, dann würde das genau so funktionieren. Die übliche Vorgehensweise wäre allerdings doch, jede Exception in eine eigene Quellcodedatei zu packen. Bzw., wenn du die nur in dem package brauchst, kannst du auch weglassen, die public zu machen, dann gehen auch mehrere in eine Quellcodedatei. Aber IMO gibt es schlimmeres als ein paar .java-Dateien für Exceptions
Du könntest die Exceptionklassen static machen, dann würde das genau so funktionieren. Die übliche Vorgehensweise wäre allerdings doch, jede Exception in eine eigene Quellcodedatei zu packen. Bzw., wenn du die nur in dem package brauchst, kannst du auch weglassen, die public zu machen, dann gehen auch mehrere in eine Quellcodedatei. Aber IMO gibt es schlimmeres als ein paar .java-Dateien für Exceptions
Hm, ich hab jetzt eine neue Datei erstellt mit dem Inhalt:
Code:
package DBClasses;
class DBDriverFailure extends Exception{
}
class DBConnectionFailure extends Exception{
}
class DBKeyNotFound extends Exception{
}
aber wenn ich die in einer anderen Datei/Klasse im selben Package werfen will mit
Code:
public class AndereKlasse {
...
void MacheIrgendEtwas() {
...
throw new DBKeyNotFound();
}
}
erkennt der Compiler sie nicht und die IDE bietet mir an ein Import für DBClasses.DBKeyNoFound anzulegen, was dann aber witzigerweise nichts am Fehler ändert. Auch eine explizite Qualifizierung
Code:
throw new DBClasses.DBKeyNotFound();
schafft keine Abhilfe.
Mache ich noch was falsch?
Gruß!
aber das war nur ein Tippfehler und nicht der Grund des Problems.
Inzwischen habe ich gemerkt, dass das Halten mehrerer Klassen in einer Datei vielleicht doch problematisch ist, denn die Sache funktioniert plötzlich, wenn ich den Code folgendermaßen abändere:
:
So ähnlich: Es wäre ein Bug NetBeans wenn es ein Feature wäre. :autsch:
Jeder Java-Compiler muß sich an die Java-Sprachspezifikation halten, sonst gäb's Chaos.
Ich vermute eher, daß, da du alle deine Exceptions in einer Datei sammeln
willst und nur eine Klasse pro Datei public sein kann, diese fehlenden public-Modifier
das Problem sind.
Es reicht doch all deine Exceptions in einem Package zu sammeln. Also für
jede Exception eine eigene Datei, sodaß diese dann alle public sein können.
Naja, vielleicht ist ja dieser Fall (gar keine public, aber mehrere package-private Classes in derselben Datei) in den Spezifikationen gar nicht definiert und das Verhalten des Compilers deshalb ebenfalls nicht.
Aber da ausser mir niemand ein Problem damit zu haben scheint, für jeweils zwei Zeilen Code
Code:
class DBDriverFailure extends Exception{
}
eine eigene Datei anzulegen, frage ich mal blöd:
Bin ich vielleicht total auf dem Holzweg und ist es vielleicht professioneller, eine eigene Exception-Klasse für das ganze Package zu erstellen und diese mit Eigenschaften zu versehen, die die konkreten Exceptions unterscheidbar machen?
Oder ist mein bisheriges Vorgehen so üblich in Java?
Gruß!
Ich selbst habe zwar noch keine Exception-Hierarchie entworfen
(ich weiß noch nicht mal wie man das schreibt ), aber
eine Klasse wie
Code:
class DBDriverFailure extends Exception{
}
die de facto nur einen neuen Namen für ein- und dieselbe Exception vergibt
und sonst gar nichts ändert/erweitert macht für mich keinen Sinn.
Sieh dir doch mal die Klassen IOException oder SQLException an.
Da wird über eine Klasse auch jeweils alles mögliche abgehandelt
und die aktuelle Exception einfach in die Fehlermeldung selbst
gepackt.
Außerdem würde es mich nerven, all deine Exception einzeln abzufangen...
Ich werd's jetzt so machen, dass ich die Exceptions in Kategorien unterteile, zB. DB-Zugriff und Sonstige. Für jede Kategorie gibt es dann maximal eine öffentliche Exception-Klasse und eine package-private.
Erweitert sind die Klassen um die Methode getError() und das sieht dann zB. so aus:
Code:
public class DBException extends Exception {
private DBError error;
public static enum DBError {
ERROR_DB_DRIVER,
ERROR_DB_CONNECTION
}
/**
* Creates a new instance of DBException
*/
DBException(DBError err) {
super();
error = err;
}
public DBError getError() {
return error;
}
}
Natürlich kann man das noch verfeinern, zB. mit mehr Attributen und Konstruktoren.
Geworfen wird eine Exception dann zB. mit
Code:
try {
// create and start JDBC object for the database access
Class.forName(driverName);
this.driverName = driverName;
} catch (ClassNotFoundException ex) {
throw new DBException(DBException.DBError.ERROR_DB_DRIVER);
}
Jetzt hoff ich halt nur noch, dass sich dieser Ansatz als praktikabel erweist.
Danke für die Anregungen soweit... ;-)
Gruß!
Gerade die IOException halte ich eher für ein abschreckendes Beispiel, weil man dem Benutzer eigentlich nicht viel mehr präsentieren kann als "Unbekannter Fehler", ohne die String-Repräsentatitio nder Exception zu analysieren (und das ist Pfui).
Alle Exceptions einzeln zu deklarieren bzw. abzufangen ist natürlich auch lästig und führt früher oder später dazu, dass jemand eben wieder ganz gloabl java.lang.Excepion behandelt.
Ich bevorzuge da einen Zwischenweg:
Code:
public abstract class DBException extends Exception {
}
public class DBDriverNotFoundException extends DBException {
}
public class DBNotSupportedException extends DBException {
}
So kann man als Verwender selbst entscheiden, ob man sich für die spezifischen Ausprägungen interessiert, oder ob man es bei der Behandlung der allgemeinen Basisklasse belässt.