Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用继承在java中定义错误代码_Java_Enums_Error Code - Fatal编程技术网

使用继承在java中定义错误代码

使用继承在java中定义错误代码,java,enums,error-code,Java,Enums,Error Code,我想模拟一些错误代码。经典的枚举方法 public enum FileError implement FormattedError { _10 ("some error with parameters [{0}] and [{1}]"), _20 ("some other error"); private final String description; private Error(String description) { this.des

我想模拟一些错误代码。经典的枚举方法

public enum FileError implement FormattedError {
    _10 ("some error with parameters [{0}] and [{1}]"),
    _20 ("some other error");

    private final String description;

    private Error(String description) {
        this.description = description;
    }

    public String getDescription(Object... parameters) {
        return // logic to format message 
    }

    ...
}
这对我不好,因为我有很多模块,每个模块都有错误代码,我不想在所有这些枚举中复制和粘贴样板文件(构造函数、getter、logic…)

所以我选择了这样实现的“手动”枚举

public class FileError extends BaseError {

    public final static FileError _10  = new FileError (10, "some message with parameters [{0}] and [{1}]");
    public final static FileError _20  = new FileError (20, "some other message");

}
我可以在BaseError中定义我的逻辑并重用它

但这仍然很糟糕,因为没有办法将变量名链接到数字(_10到10),人们复制粘贴可能会在没有注意到的情况下重复使用相同的数字。我可以添加一个测试,通过反射来检查这一点,但是我如何强制人们在实现中使用该测试呢

你们有没有更好的办法让我做到这一点


[编辑]请记住,我不想将错误代码放在属性文件中,因为我希望ide将代码中的错误代码与其消息链接起来。

要回答您关于如何检查重复使用的数字的问题,只需使用到目前为止注册的所有数字的静态集即可,并检查新的注册时,它是否还不存在:

public class BaseError {
    // ...

    private static Set<Integer> registeredNums = new HashSet<>();

    public BaseError(int N, String msg) {
        synchronized(registeredNums) {
            assert(!registeredNums.contains(N)) : "Duplicated error code";
            registeredNums.add(N);
        }

        // ...
    }
}
公共类基类错误{
// ...
私有静态集registeredNums=new HashSet();
public BaseError(int N,String msg){
已同步(注册表项){
断言(!registeredNums.contains(N)):“重复的错误代码”;
添加(N);
}
// ...
}
}

用户需要启用断言。如果您希望始终进行检查,可以手动抛出断言错误。

这两种方法的组合可能就是您想要的:

enum ErrorCode {
  _10(new FileError(10, "some message with parameters [{0}] and [{1}]")),
  _20(new FileError(20, "some other message"));

  private final FileError error;

  private ErrorCode(FileError err) {
    error = err;
  }

  public FileError getError() {
    return error;
  }
}
使用此代码,错误代码和变量之间存在显式链接。为了避免其他人使用相同的错误代码,您可以通过将构造函数包设置为私有来阻止他们完全创建自己的
FileError
实例。如果这不是一个选项,您可以创建一个额外的子类,如下所示:

public class UserDefinedFileError extends FileError {
  public UserDefinedFileError(int code, String msg){
    super(checkCode(code),msg);
  }

  static int checkCode(int code){
    if(code <= 100){ // or check if it exists in a set of used codes
      throw new IllegalArgumentException("Error codes lower than 100 are reserved.");
    }
  }
}
public类UserDefinedFileError扩展FileError{
public UserDefinedFileError(int代码,字符串msg){
超级(检查代码(代码),消息);
}
静态整数校验码(整数码){
如果(code有必要使用一些样板代码,但是您可以通过使
enum
实现一个
接口
,并将大部分功能静态地放在
接口
中来将其保持在最低限度-当然,假设您使用的是Java-7+

interface Error {

    /**
     * Keeps track of error ranges - for sanity check when errors are registered.
     */
    static final Map<ErrorRange, Set<? extends Error>> errors = new HashMap<>();
    /**
     * Lookup range.
     */
    static final Map<Error, ErrorRange> range = new HashMap<>();

    public static <E extends Enum<E> & Error> void register(ErrorRange errorRange, Class<E> theClass) {
        // Keep track of all errors - TODO - Make sure each is registered only once.
        errors.put(errorRange, EnumSet.allOf(theClass));
        // We need the range.
        for (Error e : theClass.getEnumConstants()) {
            range.put(e, errorRange);
        }
    }

    /**
     * Get a formatted string for the error with the provided parameters.
     */
    static <E extends Enum<E> & Error> String format(E error, Object... parameters) {
        // The error number comes from it's range + its ordinal.
        int errNo = range.get(error).range + error.ordinal();
        // The string comes from the formatted description.
        return errNo + "\t" + String.format(error.getDescription(), parameters);
    }

    // All Errors must have a description.
    public String getDescription();

}

/**
 * Register of all error ranges.
 */
enum ErrorRange {

    // All File errors start at 10,000
    FileError(10_000);

    final int range;

    private ErrorRange(int range) {
        this.range = range;
    }

}

public enum FileError implements Error {

    ParameterError("some error with parameters [{0}] and [{1}]"),
    OtherError("some other error");

    //<editor-fold defaultstate="collapsed" desc="Description">
    // Start boilerplate
    private final String description;

    private FileError(String description) {
        this.description = description;
    }

    @Override
    public String getDescription() {
        return description;
    }
    // End boilerplate
    //</editor-fold>

}

static {
    // Statically register me with the Error object.
    Error.register(ErrorRange.FileError, FileError.class);
}
接口错误{
/**
*跟踪错误范围-用于在注册错误时进行健全性检查。
*/

静态最终地图希望您能对此有所了解:

public enum FileError {
    SOME_ERROR1("0", "Error something1"),
    SOME_ERROR2("1", "Error something2"),
    SOME_ERROR3("2", "Error something3"),

    private final String code;
    private final String message;

    FileError(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public String get() {
        return new CustomException(code, message).toString();
    }
}
你是
CustomException
class

public class CustomException {

    ...

    @Override
    public String toString() {
        return String.format(Locale.getDefault(), "%s, %s", code, message);
    }
}

集成测试应验证没有重复使用任何数字,最好是在单元测试之后直接运行这些测试,以便测试可以使用
BaseError.class.getsubclass()
快速获取所有子类型。可能的重复