【问题标题】:Add an attribute to any java exception为任何 java 异常添加属性
【发布时间】:2016-12-19 21:19:53
【问题描述】:

我想通过向它们添加属性来自定义 java 异常类。它可以像以下属性一样简单:

boolean isThisStupid;

void setIsThisStupid(boolean iValue);
boolean getIsThisStupid();

每次我实例化一个异常时,比如 NullPointerException 或 IllegalArgumentException,它都会包含这个属性。

由于我没有Java的源代码,当然不能编辑Exception基类。

我考虑过使用装饰器模式,使用实现 IException 接口的“ExceptionDecorator”类,但是,这样做会丢失初始异常类型,这是我不想要的。例如:

IException mException = new ExceptionDecorator( new NullPointerException() );

我会得到:

mException instanceof ExceptionDecorator; //true
mException instanceof NullPointerException; //false

我希望我的自定义异常是 NullPointerException 的一个实例。

这是完全通用的,我希望它适用于任何异常的子类。

这甚至可能吗?如果是,也许有一种模式可以帮助我,但我不知道?

我已经尽力说清楚了,如果我不清楚,请询问更多详细信息,我将重新表述最初的主题。

谢谢

【问题讨论】:

    标签: java exception decorator


    【解决方案1】:

    我希望我的自定义异常是 NullPointerException 的一个实例。

    在编译时是不可能的。为了做你想做的事,你应该在运行时使用 Javasist 动态创建你的异常类。

    否则对于静态类型,您可以使用装饰器。装饰器必须使用与装饰对象相同的接口/类。它是装饰器的基础。

    在您的情况下,基类不能是您创建的新接口,因为您无法更改现有异常的代码。所以装饰器和装饰对象之间的通用抽象类是Exception

    你可以有一个这样的装饰器:

    public class DecoratorException extends Exception{
    
       private Exception decorated;
       private boolean isStupid;
    
       public DecoratorException(Exception exception){
         this.decorated = exception;
       }
    
       public void setStupid(boolean iValue){
          // TODO
       }
       public boolean getStupid{}{
          // TODO
       }
    
       // get effective exception
       public Exception getEffectiveException(){
         return decorated;
       }
    
       // decorate the method you wish 
       // for example toString()
       public String toString(){
           return  decorated.toString() + ", isStupid=" + isStupid);
       }
    
    }
    

    装饰器的想法是为被装饰的对象添加行为。
    在我的示例中,我修饰了 toString() 方法以显示新字段及其值。

    然后你可以引发这样的异常:

    Exception e = new DecoratorException(new IllegalArgumentException());
    e.setStupid(true);
    throw e;
    

    【讨论】:

      【解决方案2】:

      谢谢大家的回答,似乎没有什么能真正满足我的需要。所以我可能只是改变我的想法,而不是强迫一些会变得尴尬和不可维护的东西

      【讨论】:

      • 优秀的结论:)
      【解决方案3】:

      我认为你最好的选择是继续使用你所描述的装饰器模式,而不是使用instance of,而是在你的异常类(#containsInstanceOf 或其他东西)中创建另一个方法并在你的代码中使用它检查包含的类型。

      我认为添加您想要的行为的唯一方法是像 Lombok 那样弄乱字节码,或者通过创建代理对象。两者都非常混乱,使用装饰器模式并处理instance of 不起作用的事实可能更容易。

      【讨论】:

      • 我曾经遇到过这样的事情,但有没有办法让它与 try {} catch{} 一起工作?
      【解决方案4】:

      要让异常类扩展 NullPointer,请执行以下操作:

      public MyNewException extends NullPointerException
      {
          /*define methods and variables*/
      }
      

      要让一个类处理任何异常的子类,您必须按如下方式定义它:

      public MyNewException extends Exception
      {
          /*define stuff*/
      }
      

      如果您不想这样做,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多