【问题标题】:Inheritance and static members in JavaJava中的继承和静态成员
【发布时间】:2011-07-15 14:26:45
【问题描述】:

我正在开发一个包含几个模块的项目。我想在每个模块中提供具有静态填充内部结构的自定义异常的能力,例如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. 抽象异常的所有子类都存在 ERRORS 映射
  2. 同时访问静态 ERRORS 字段。

问题是,如何避免这些问题,可能有人对我的问题有更好的解决方案?

【问题讨论】:

  • 您想在模块之间共享错误消息吗?
  • 并发访问静态ERRORS会出现什么样的问题?这些静态成员没有脏读/写,不是吗?
  • 也许你应该改用java.util.logging。您真的需要将这些错误保留在内存中吗?
  • 2Brian 不,我不想要。对于公共父类,我只想封装相同的逻辑填充和使用错误映射。
  • Hashtable 已同步,而 HashMap 未同步。

标签: java inheritance static custom-exceptions


【解决方案1】:

这种设计行不通,因为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();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多