6
votes

Emballage des exceptions projetées dans Super / Ce constructeur appelle à d'autres exceptions

Je veux que l'API de mon module ne jette que MyPackagesPécificexception à chaque fois que tout ne va pas et le module incapable d'effectuer sa tâche. (L'exception originale sera donnée comme cause de la mypackagespecificexception).

Maintenant, pour un constructeur, j'avais besoin d'une URL comme paramètre pour localiser une ressource. Je voudrais également créer un constructeur alternatif sur lequel une représentation de chaîne de l'URL peut être donnée: xxx

car le constructeur d'URL jette une erreur malformedurlexception, je veux envelopper dans un MypackagespecificeXceptionException en faisant: xxx

mais, ce qui précède n'est pas valide, car le super () ou cet appel de constructeur doit se produire sur la première ligne du constructeur.

Le même problème s'applique si le super () ou ce () constructeur jette une exception que je veux envelopper quelque chose d'autre.

Comment dois-je résoudre ce problème? Ou est ce que j'essaie de faire de mauvaises pratiques?


0 commentaires

3 Réponses :


3
votes

Si cela correspond à votre code, vous pouvez utiliser une méthode de créateur statique à la place:

private MyClass(String urlString) { ... }

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


1 commentaires

C'est en fait mieux que la réponse acceptée, car elle fonctionnera pour le cas générique, alors que la réponse acceptée ne fonctionnera que si vous pouvez trouver (et "convertir" en) un constructeur de superclasse qui ne jette pas d'exceptions indésirables. Motif d'usine FTW, je suppose.



6
votes

Essayez ce qui suit:

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);
    }
  }
}


1 commentaires

Je ne peux pas croire que je n'y pensais pas. Simple, et fait exactement ce que je veux.



0
votes

au lieu d'utiliser ceci () avoir une méthode Init () commune () qui prend l'argument de l'URL de cette façon, il n'a pas besoin d'être la première ligne du constructeur.

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
}


2 commentaires

Cela vous empêche d'attribuer des paramètres de constructeur aux champs finaux, ce qui rend plus difficile de faire des classes immuables. L'attribution de champs finaux ne peut être effectuée que dans le constructeur.


Étant une solution viable à l'exemple que j'ai affiché, cela ne fonctionne toutefois pas si l'URL doit être transmise à un super constructeur, c'est pourquoi j'ai préféré les autres solutions.