Добавить атрибут к любому исключению Java

Я хотел бы настроить класс исключений Java, добавив к ним атрибут. Это может быть так же просто, как следующий атрибут:

boolean isThisStupid;

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

Каждый раз, когда я создаю экземпляр исключения, например, NullPointerException или IllegalArgumentException, оно будет содержать этот атрибут.

Поскольку у меня нет исходного кода Java, я, конечно, не могу редактировать базовый класс Exception.

Я рассмотрел использование шаблона декоратора, использование класса "ExceptionDecorator", реализующего интерфейс IException, однако, делая это, я потерял бы исходный тип исключения, который я не хочу. Например для:

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

Я бы получил:

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

Я хочу, чтобы мое пользовательское исключение было экземпляром NullPointerException.

Это совершенно универсально, я хочу, чтобы это работало с любым подклассом исключения.

Это вообще возможно? Если да, может быть, есть какая-то модель, которая может мне помочь, и я не знаю о чем?

Я сделал все возможное, чтобы было ясно, если нет, пожалуйста, попросите более подробную информацию, и я перефразирую исходную тему.

Спасибо

4 ответа

Решение

Спасибо вам всем за ваши ответы, кажется, что ничто не может действительно удовлетворить то, что мне нужно. Так что я могу просто изменить свою идею, вместо того, чтобы принуждать что-то, что могло бы стать неудобным

Я хочу, чтобы мое пользовательское исключение было экземпляром 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);
   }

}

Идея Decorator заключается в добавлении поведения к декорированному объекту.
В моем примере я украсил toString() метод для отображения нового поля с его значением.

Затем вы можете создать исключение, подобное этому:

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

Я думаю, что вам лучше всего продолжить с использованием шаблона декоратора, как вы описали, и вместо того, чтобы использовать instance ofсоздайте другой метод в вашем классе исключений (#containsInstanceOf или что-то) и использовать это в своем коде, чтобы проверить содержащийся тип.

Я думаю, что единственный способ добавить поведение, которое вы хотите, - это связываться с байт-кодом, как это делает Lombok, или создавать прокси-объекты. Оба из них довольно грязные, и, вероятно, проще просто использовать шаблон декоратора и иметь дело с тем, что instance of не сработает

Чтобы получить класс исключения для расширения NullPointer, сделайте что-то вроде этого:

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

Чтобы класс работал с любым подклассом исключения, вы должны определить его следующим образом:

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

Дайте мне знать, если это не то, что вы хотите сделать.

Другие вопросы по тегам