2009-08-14 2 views
6

Ich möchte die API meines Moduls nur MyPackageSpecificException werfen, wenn etwas schief geht und das Modul seine Aufgabe nicht ausführen kann. (Die ursprüngliche Ausnahme wird als Ursache für die MyPackageSpecificException angegeben).Wrapping Ausnahmen ausgelöst in Super/dieser Konstruktor Aufrufe in andere Ausnahmen

Jetzt brauchte ich für einen Konstruktor eine URL als Parameter, um eine Ressource zu finden. Ich möchte auch einen alternativen Konstruktor machen, an die eine String-Darstellung der URL angegeben werden kann:

public MyClass(String urlString) throws MalformedURLException{ 
    this(new URL(urlString)); 
} 

Da die URL Konstruktor MalformedURLException wirft, ich will es in eine MyPackageSpecificException wickeln, indem Sie:

public MyClass(String urlString) throws MyPackageSpecificException{ 
    try{ 
     this(new URL(urlString)); 
    } catch (MalformedURLException e){ 
     throw new MyPackageSpecificException(e); 
    } 
} 

Aber das obige ist nicht gültig, da der Konstruktoraufruf super() oder this() in der ersten Zeile des Konstruktors auftreten muss.

Das gleiche Problem gilt, wenn der Konstruktor super() oder this() eine Ausnahme auslöst, die ich in etwas anderes einwickeln möchte.

Wie soll ich das lösen? Oder ist das, was ich versuche, schlechte Praxis zu machen?

Antwort

6

Versuchen Sie Folgendes:

public class MyClass 
{ 
    private URL url; 

    public MyClass(URL url) 
    { 
    this.url = url; 
    } 

    public MyClass(String urlString) throws MyPackageSpecificException 
    { 
    this(toURL(urlString)); 
    } 

    private static URL toURL(String urlString) throws MyPackageSpecificException 
    { 
    try 
    { 
     return new URL(urlString)); 
    } 
    catch (MalformedURLException e) 
    { 
     throw new MyPackageSpecificException(e); 
    } 
    } 
} 
+0

Ich kann nicht glauben, dass ich nicht darüber nachgedacht habe. Einfach und macht genau das, was ich will. – Alderath

3

Wenn es Ihr Code passt, können Sie ein statisches Konzept Verfahren statt:

private MyClass(String urlString) { ... } 

public static MyClass createMyClass(String urlString) throws MyPackageSpecificException { 
    try { 
    new MyClass(urlString); 
    catch (Exception e) { 
    throw new MyPackageSpecificException(e); 
    } 
} 
+1

Dies ist eigentlich besser als die Antwort akzeptiert, weil es für den generischen Fall funktionieren wird, während die akzeptierte Antwort nur funktioniert, wenn Sie (und „convert“ zu) einen Oberklassenkonstruktors, die nicht werfen nicht finden unerwünschte Ausnahmen. Fabrikmuster FTW, denke ich. – Coderer

0

Statt dessen verwenden() haben eine gemeinsame Methode init() Das nimmt das URL-Argument so, dass es nicht die erste Zeile des Konstruktors sein muss.

public MyClass(String url) throws MyPackageSpecificException 
{ 
    try 
    { 
    init(new URL(url)); 
    } 
    catch (MalformedURLException e) 
    { 
    throw new MyPackageSpecificException(e); 
    } 
} 

public MyClass(URL url) 
{ 
    init(url); 
} 

private void init(URL url) 
{ 
    // do constructor work here 
} 
+1

Dies verhindert, dass Sie den endgültigen Feldern Konstruktorparameter zuweisen, wodurch es schwieriger wird, unveränderliche Klassen zu erstellen. Das Zuweisen finaler Felder kann nur im Konstruktor erfolgen. –

+0

Als eine praktikable Lösung für das Beispiel, das ich gepostet habe, funktioniert dies jedoch nicht, wenn die URL an einen Superkonstruktor übergeben werden muss, weshalb ich die anderen Lösungen bevorzuge. – Alderath

Verwandte Themen