Добавить атрибут к любому исключению 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*/
}
Дайте мне знать, если это не то, что вы хотите сделать.