spring Java -需要在构造函数调用super()之前初始化变量

1tu0hz3e  于 12个月前  发布在  Spring
关注(0)|答案(2)|浏览(258)

注意:部分代码将使用西班牙语。

嗨,我为我的Sping Boot 应用程序做了一个很好的异常模型,这样我抛出的每个个性化异常都会创建一个个性化的响应(在本例中,它是一个名为ErrorModel得类),这样我就可以用@ExceptionHandler捕获@RestControllerAdvice中得异常,并且只返回该特定异常创建的errorModel。在个性化异常中创建的每个errorModel的特殊之处是codedescription

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(ClienteSinMorasException.class)
  @ResponseStatus(HttpStatus.NOT_FOUND)
  @ResponseBody
  public ErrorModel manejoDeClienteSinMoras(ClienteSinMorasException ex) {
      return ex.getErrorModel();
  }
}

个字符
因此,因为每个异常都是相同的,并且工作方式相同,唯一的区别是codecodigo)和descriptiondescipcion),所以我创建了这个,它工作得很好:

public abstract class IErrorException extends RuntimeException {
    @Getter
    private final ErrorModel errorModel;

    public abstract String getCodigo();

    public abstract String getDescripcion();

    public IErrorException() {
        super();
        this.errorModel = new ErrorModel(this.getCodigo(), this.getDescripcion(), null);
    }

    public IErrorException(ArrayList<HashMap<String, String>> errores) {
        super();
        this.errorModel = new ErrorModel(this.getCodigo(), this.getDescripcion(), errores);
    }

    public IErrorException(String errorKey, String errorValue) {
        super();
        ArrayList<HashMap<String, String>> errores = new ArrayList<>();
        errores.add(new HashMap<>(Map.of(errorKey, errorValue)));
        this.errorModel = new ErrorModel(this.getCodigo(), this.getDescripcion(), errores);
    }

}
// One of the exceptions
@Getter
public class ClienteSinMorasException extends IErrorException {

    private final String codigo = "code";
    private final String descripcion = "desc";

    public ClienteSinMorasException() {
        super();
    }

    public ClienteSinMorasException(ArrayList<HashMap<String, String>> errores) {
        super(errores);
    }

    public ClienteSinMorasException(String errorKey, String errorValue) {
        super(errorKey, errorValue);
    }

}

的字符串
这是完美的(除了那些超级,但无论如何),但最近,他们要求我改变它,使codedescription是从.yml属性读取,这样的值可以在运行时改变,而不需要重新运行应用程序。
我开始明白,这起作用的唯一原因是,当我在抽象类中执行this.getCodigo()时,explicit primitive类型的final字段“有点已经存在(在本例中,返回“code”)。如果不是final,也不是explicit primitive类型,则不起作用,它在构造函数执行后加载所有内容,因此我最终创建了一个new ErrorModel(null, null, null)。另外,super()必须是构造函数中的第一个元素,因此我无法正确地初始化变量。

// One of the exceptions
@Getter
public class ClienteSinMorasException extends IErrorException {

    private final String codigo = Yml.get("cod");
    private final String descripcion = Yml.get("desc");

    public ClienteSinMorasException() {
        super();
    }

    public ClienteSinMorasException(ArrayList<HashMap<String, String>> errores) {
        super(errores);
    }

    public ClienteSinMorasException(String errorKey, String errorValue) {
        super(errorKey, errorValue);
    }

}


这不管用,老实说,我不知道该怎么办。

f5emj3cl

f5emj3cl1#

字段初始化器直到稍后才运行。然而,这两个字段似乎没有任何功能。你不需要它们。它们最多是作为缓存Yml读取器值的一种有点蹩脚的方式存在。蹩脚的是,每个异常的示例都会重新创建它们,如果缓存是重点,在Yml类本身中这样做会更有效。
因此,完全删除字段。要么它们根本没有任何意义,要么它们的意义是作为缓存(即避免重复锤击磁盘以多次重新读取YML文件)。如果它是缓存-这是它的错误位置,请编辑Yml的代码以在那里添加缓存行为。无论哪种方式,对这种异常类型的正确处理都是:

public class ClienteSinMorasException extends IErrorException {

    @Override public String getCodigo() {
      return Yml.get("cod");
    }

    @Override public String getDescripcion() {
      return Yml.get("desc");
    }

    public ClienteSinMorasException() {
        super();
    }

    public ClienteSinMorasException(ArrayList<HashMap<String, String>> errores) {
        super(errores);
    }

    public ClienteSinMorasException(String errorKey, String errorValue) {
        super(errorKey, errorValue);
    }
}

字符串
这避免了问题:这里没有字段,所以也没有字段初始化器,所以你不会遇到任何关于初始化序列的问题。

oug3syen

oug3syen2#

所以我是最初发布这个问题的人。上面的答案是我用的.....直到我最近才明白,从我的Angular 来看,这一切都是愚蠢的。这里是我的新答案。
所以,基本上,我是搬起石头砸自己的脚。原因很简单:**我不需要在初始化类时做所有这些!!! 我可以在调用.getErrorModel()的时候做,这是我需要的时候,而不是之前。这是一个如此明显的疏忽,似乎我被@Getter蒙蔽了双眼,尝试使用它,而不是自己编写任何类型的getter。这是新的解决方案。

public abstract class IErrorException extends RuntimeException {

    protected ArrayList<HashMap<String, String>> errores = null;

    public abstract String getCodigo();

    public abstract String getDescripcion();

    public IErrorException() {
        super();
    }

    public IErrorException(ArrayList<HashMap<String, String>> errores) {
        super();
        this.errores = errores;
    }

    public IErrorException(String errorKey, String errorValue) {
        super();
        this.errores = new ArrayList<>();
        this.errores.add(new HashMap<>(Map.of(errorKey, errorValue)));
    }

    public ErrorModel getErrorModel() {
        return new ErrorModel(this.getCodigo(), this.getDescripcion(), this.errores);
    }

}

字符串
然后:

public class ClienteSinMorasException extends IErrorException {

    public ClienteSinMorasException() {
        super();
    }

    public ClienteSinMorasException(ArrayList<HashMap<String, String>> errores) {
        super(errores);
    }

    public ClienteSinMorasException(String errorKey, String errorValue) {
        super(errorKey, errorValue);
    }

    @Override public String getCodigo() {
      return "Codigo";
    }

    @Override public String getDescripcion() {
      return "descripcion";
    }
}


我认为这是目前为止最好的解决方案,因为它不会不必要地接近边缘。

相关问题