Наследование и статические члены в Java - PullRequest
1 голос
/ 15 июля 2011

Я работаю над проектом, который содержит пару модулей. Я хочу предоставить возможность в каждом модуле иметь пользовательское исключение, которое статически заполняет внутреннюю структуру, например HashMap, из файла свойств с пользовательскими парами error_code-error_message. У меня есть базовое абстрактное пользовательское исключение, которое содержит статическое свойство:

public abstract class AbstractException extends RuntimeException{
   public static Map<String, String> ERRORS = new HashMap<String, String>();
   public String code;
   // getters and setter for code ommited

   public static init(String fileName, Class<?> clazz){
    // read properties file
    // populate map
   }

   public static String getMessageByCode(String code){
    //
   String mess = ERRORS.get(code);
   // in case of null message provide default message about unknown error
   }

   public AbstractException(String code){
      super(getMessageByCode(code));
      this.setCode(code);
   }

   public AbstractException(Throwable thr){
      super(getMessageByCode("ERROR_999"), thr);
      this.setCode(code);
   }

   public AbstractException(Throwable thr, String msg){
      super(getMessageByCode("ERROR_999") + " " + msg, thr);
      this.setCode(code);
   }

}

Простое пользовательское исключение

public class MyException extends AbstractException{
 static{
   // populate internal map with module-specific errors
   init("module1.errors.properties", MyException.class);
 }     

public MyException(String code){
 super(getMessageByCode());
}
// rest code omited

}

Простое использование пользовательского исключения в коде:

throw new MyException("ERROR_404");

Позволяет увидеть то, что я вижу в этом коде:

  1. Карта ОШИБКИ существует для всех дочерних классов абстрактного исключения
  2. Параллельный доступ к статическому полю ERRORS.

Вопрос в том, как избежать этих проблем, может быть, у кого-то есть лучшее решение моей проблемы?

1 Ответ

1 голос
/ 15 июля 2011

Этот дизайн не будет работать, потому что будет только одна копия ERRORS, общая для всех подклассов. Одним из возможных решений является ExceptionFactory, который управляет различными картами ERRORS и может создавать для вас исключения из необходимых подклассов. Например

public static class AbstractException extends RuntimeException 
{ 
    String code;
    String message;
    public void setCode(String code) { this.code = code; }
    public void setMessage(String message) { this.message = message; }
}

public static class MyException1 extends AbstractException{ }

public static class MyException2 extends AbstractException{ }

public static class ExceptionFactory
{
    private Map<Class<?>,Map<String,String>> errorMaps = new HashMap<Class<?>, Map<String,String>>();
    public void register(Class<? extends AbstractException> exType, String fileName)
    {
        Map<String,String> errors = new HashMap<String,String>();
        // load errors from fileName
        errorMaps.put(exType, errors);
    }

    public <T extends AbstractException> T newException(Class<T> exType, String code)
    {
        Map<String,String> map = errorMaps.get(exType);
        String message = map.get(code);
        T ex;
        try
        {
            ex = exType.newInstance();
            ex.setCode(code);
            ex.setMessage(message);
            return ex;
        }
        catch(InstantiationException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch(IllegalAccessException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...