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

问题描述 投票:0回答:1

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

嗨。我为我的 Spring Boot 应用程序创建了一个很好的异常模型,这样我抛出的每个个性化异常都会创建一个个性化响应(在本例中,它是一个名为

ErrorModel
的类),这样我就可以在
@RestControllerAdvice
中使用
@ExceptionHandler
,然后返回该特定异常创建的
errorModel
。在个性化例外中创建的每个
errorModel
的特殊之处在于
code
description

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(ClienteSinMorasException.class)
  @ResponseStatus(HttpStatus.NOT_FOUND)
  @ResponseBody
  public ErrorModel manejoDeClienteSinMoras(ClienteSinMorasException ex) {
      return ex.getErrorModel();
  }
}
@Getter
@AllArgsConstructor
public class ErrorModel {
    private final String codigo;
    private final String descripcion;
    private final ArrayList<HashMap<String, String>> errores; //don't take this into consideration
}

因此,因为每个异常都是相同的,并且工作原理相同,唯一的区别是

code
(
codigo
) 和
description
(
descipcion
),我创建了这个,并且运行良好:

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);
    }

}

这是完美的(除了那些超级,但无论如何),但最近,他们要求我更改它,以便从 .yml 属性读取

code
description
,以便可以在运行时更改值,而无需需要重新运行应用程序。这个简单的改变打破了一切。

我开始明白,这样做有效的唯一原因是因为当我在抽象类中执行

final
时,
explicit primitive
类型的
this.getCodigo()
字段“有点已经存在”(在本例中,这返回“代码”)。如果它不是
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);
    }

}

这行不通,老实说我不知道该怎么办。

java spring constructor abstract-class super
1个回答
0
投票

字段初始值设定项稍后才会运行。但是,您拥有的这两个字段似乎没有任何功能。你不需要它们。充其量,它们只是作为缓存 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);
    }
}

这避免了这个问题:没有字段,因此没有字段初始值设定项,因此您不会遇到任何有关初始化序列问题的问题。

© www.soinside.com 2019 - 2024. All rights reserved.