如何用Java编写异常工厂

如何用Java编写异常工厂,java,exception,frameworks,factory,Java,Exception,Frameworks,Factory,我们目前正在开发一个内部使用的框架。我们现在要使用标准化的异常ID和消息。开发人员只需提供一个ID和一条默认消息,框架就会查找相关消息(如果可能)或使用默认消息(如果无法检索消息)。 第一个想法是编写一个异常工厂,强制开发人员提供错误ID,然后在工厂方法中查找消息。这种方法的问题是,在stacktrace(创建异常的工厂方法)中添加了一个额外的帧。那不太好。几乎每一个试图隐藏创造的解决方案都有这个问题。 第二个想法是将消息查找和我们的异常类耦合起来,并编写一个抽象异常类,该类接受构造函数中的错误

我们目前正在开发一个内部使用的框架。我们现在要使用标准化的异常ID和消息。开发人员只需提供一个ID和一条默认消息,框架就会查找相关消息(如果可能)或使用默认消息(如果无法检索消息)。 第一个想法是编写一个异常工厂,强制开发人员提供错误ID,然后在工厂方法中查找消息。这种方法的问题是,在stacktrace(创建异常的工厂方法)中添加了一个额外的帧。那不太好。几乎每一个试图隐藏创造的解决方案都有这个问题。 第二个想法是将消息查找和我们的异常类耦合起来,并编写一个抽象异常类,该类接受构造函数中的错误ID并处理消息查找。但这也不是很好,因为它缺少松耦合。 第三个想法是让开发人员每次都编写消息的查找。。也很糟糕

你有什么想法吗

另外,我想这是我第一次需要Java中的宏

代码中的不同方法:

一,

二,

三,


可以编辑堆栈跟踪,删除不需要的元素。如果所有异常的构造函数都需要相同的数据,请使用单个createException,否则请使用createCustomException方法

这将删除不必要的堆栈跟踪元素

public static <T extends Throwable> T adjustStackTrace(T ex, int removedElements) {
    //use an explicit constraint for removedElements
    if (removedElements < 1) {
        throw new IllegalArgumentException("removedElements may not be less than 1");
    }
    final StackTraceElement[] stack = ex.getStackTrace();
    //or an implicit constraint
    removedElements = Math.max(removedElements, stack.length);

    final StackTraceElement[] newStack = new StackTraceElement[stack.length - removedElements];
    System.arraycopy(stack, removedElements, newStack, 0, stack.length - removedElements);
    ex.setStackTrace(newStack);
    return ex;
}
或者,您可以使用单个方法并传递所需的异常类:

public  Exception createException(Class<?> exClass, Object... someExceptionSpecificData) {...}
此示例基于来自oval框架的net.sf.oval.internal.util.Assert,请参见

如何创建错误消息工厂而不是异常工厂?
public TechnicalException(ErrorId errorId, String defaultmsg) {
    super(defaultmsg);
    //get msg here and set on a new field cause detailMessage is not accessible. Also overwrite toString();
}

throw new TechnicalException(new ErrorId("123"), "defaultmsg");
ErrorId errorId = new ErrorId("123");
String msg = someProvider.getMessage(errorId);
throw new TechnicalException(errorId, msg);
public static <T extends Throwable> T adjustStackTrace(T ex, int removedElements) {
    //use an explicit constraint for removedElements
    if (removedElements < 1) {
        throw new IllegalArgumentException("removedElements may not be less than 1");
    }
    final StackTraceElement[] stack = ex.getStackTrace();
    //or an implicit constraint
    removedElements = Math.max(removedElements, stack.length);

    final StackTraceElement[] newStack = new StackTraceElement[stack.length - removedElements];
    System.arraycopy(stack, removedElements, newStack, 0, stack.length - removedElements);
    ex.setStackTrace(newStack);
    return ex;
}
public static TechnicalException createTechnicalException(Object... someExceptionSpecificData) {
    StringBuilder sb = new StringBuilder();
    sb.append("...").append("..."); //create a message

    //process the someExceptionSpecificData
    Object[] someNewData = someExceptionSpecificData;

    TechnicalException ex = new TechnicalException(sb.toString(), someNewData);

    ex = adjustStackTrace(ex, 1 /*remove StackTraceElement, related to this method call*/);
    return ex;
}
public  Exception createException(Class<?> exClass, Object... someExceptionSpecificData) {...}
public void useExceptionFactory() {
    throw ExceptionFactory.createTechnicalException();
}

public void adjustEvenMore() {
    //adjust even more to hide the implementation of your library
    throw ExceptionFactory.adjustStackTrace(ExceptionFactory.createTechnicalException(),1);
}