Exceptions & Co: Best Practice?

ComFreek

Mod | @comfreek
Moderator
Guten Abend,

ich habe gerade einen sehr kleinen Interpreter in Java fertig, allerdings stoße ich an folgendes Design-Problem:

Welche Exception soll ich bei einem Syntax-Fehler in meiner Skriptsprache werfen? Welche bei nicht existierenden Variablen/Funktionen?
Momentan habe ich sowas:
Java:
package com.example.interpreter;

public class SyntaxException extends RuntimeException {
	private static final long serialVersionUID = 1L;
	
	public String message;
	
	public SyntaxException(String msg) {
		message = msg;
	}
}

package com.example.interpreter;

public class NotFoundException extends RuntimeException {
	private static final long serialVersionUID = 1L;
	public String message;
	
	public NotFoundException(String msg) {
		message = msg;
	}
}
Das Hauptmerkmal ist natürlich die klare Redundanz hier (DRY-Prinzip wo bist du ? ;) ). Man kann ja leider nicht mehrfach in Java erben, sodass das Erben von RuntimeException und einer eigenen Klasse, die die message-Funktionalität kapselt, nicht hinhaut.

Laut Effective Java soll man built-in-Exceptions eigenen vorziehen, nur leider gibt es nichts für Syntax- oder NotFound-Fehler :(



Ich bedanke mich schonmal herzlich für Antworten :)
 
Hi,
also so ganz verstehe ich deine Frage leider nicht, was du letztenendes haben willst.

Du könntest beispielsweise deine eigene Klasse (SyntaxException) von RuntimeException (SyntaxException extends RuntimeException) ableiten und dann von dieser ableiten (NotFoundException extends SyntaxException). Dann hast du immer ein Exception-Typ, der von RuntimeException abgeleitet ist. Wenn das deine Frage war?

Gruß

Fabio
 
Hallo Fabio,

danke für die Antwort!
Meine Frage war: Welche Exceptions soll ich bei einem Syntax-Verstoß oder beim Aufruf einer nicht deklarierten Funktion werfen?

Ich habe ja momentan wie oben im Code zwei Exceptions von RuntimeException abgeleitet, allerdings muss ich bei beiden die Message-Funktionalität implementieren (weil ich die schon gerne haben möchte).
Und dass ich genau bei beiden die Message-Funktionalität implementiere, möchte ich vermeiden (Redundanz!).
Was ist der beste Ansatz hierzu?

Fabio Hellmann hat gesagt.:
Du könntest beispielsweise deine eigene Klasse (SyntaxException) von RuntimeException (SyntaxException extends RuntimeException) ableiten und dann von dieser ableiten (NotFoundException extends SyntaxException).
Logisch gesehen sollte aber NotFoundException nicht von SyntaxException erben.
 
Es ist schwierig mit dem bisschen an Information eine Exception-Hierachie aufzubauen, aber ich könnte mir spontan soetwas vorstellen:

MyScriptException extends RuntimeException

MyScriptInterpreterException extends MyScriptException
MyScriptSyntaxException extends MyScriptInterpreterException

MyScriptRuntimeException extends MyScriptException
NoSuchFunctionException extends MyScriptRuntimeException

Du Unterscheides sozusagen zwischen Deinen eigenen Laufzeitfehlern und deinen Compiler- bzw. Interpreter-Fehlern. Ich würde mir auch überlegen das Klassen-Präfix "MyScript" wegzulassen, da sich die Herkunft ja eigentlich aus dem Package ergibt.
 
Danke für deine Antwort Billie!

Ich werde es jetzt wahrscheinlich so realisieren:
Code:
RuntimeException
|
|
|--MessageBasedException (hat jmd. einen besseren Namen?)
    |
    |
    |--InterpreterException
        |
        |
        |--SyntaxException
        |--NoSuchFunctionException
        |--NoSuchVariableException
 
Wozu die MessageBasedException? Wenn Du in der InterpreterException ein (final) Attribut "Message" definierst und das Attribut im Konstruktor initalisierst müssen alle Unterklassen (Syntax, NoSuchFunction, etc.) eine Message übergeben.

Wenn Deine "Message" allerdings auch nur auf einen String basiert, solltest Du evtl. das bestehende Message-Attribut der Klasse Throwable verwenden. Dann musst Du in der InterpreterException nur den Konstruktor mit dem Message-Attribut überschreiben:

Java:
public class InterpreterException extends RuntimeException {

  public InterpreterException(String message) {
    super(message);
  }

}
 
Zuletzt bearbeitet von einem Moderator:
Ich wusste gar nicht, dass Throwable sowas schon implementiert ;) Danke!



PS: Wer hat denn hier schon auf Erledigt gedrückt ? Ich bin ein Mod, ich kann das schon selbst :D
 

Neue Beiträge

Zurück