Java中的继承和静态成员

发布于 2024-11-24 02:48:56 字数 1579 浏览 4 评论 0原文

我正在开发一个包含几个模块的项目。我想在每个模块中提供一个自定义异常的功能,该异常可以使用自定义 error_code-error_message 对从属性文件静态填充内部结构,例如 HashMap。 我有一个包含静态属性的基本抽象自定义异常:

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. 对静态错误字段的并发访问。

问题是,如何避免这些问题,也许有人有更好的解决方案来解决我的问题?

I am working on a project which contains a couple of modules. I want to provide the ability in every module to have a custom exception that statically populates internal structure, e.g. HashMap, from property file with custom error_code-error_message pairs.
I have a base abstract custom exception what contains a static property:

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

}

Simple custom exception

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

}

Simple usage of custom exception in code:

throw new MyException("ERROR_404");

Propblems what I can see in this code:

  1. ERRORS map exists for all child classes of abstract exception
  2. Concurrent access to static ERRORS field.

Question is, how to avoid these problems, may be someone have a better solution of my problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风柔一江水 2024-12-01 02:48:56

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

This design won't work because there will be only one copy of ERRORS, shared among all subclasses. One possible solution is an ExceptionFactory that manages the various ERRORS maps and can create and exceptions of the required subclasses for you. For example

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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文