提问人:Gonzalo Martinez 提问时间:10/19/2023 更新时间:10/19/2023 访问量:72
Java - 在构造函数调用 super() 之前需要初始化变量
Java - Need to initialize variable before Constructor calls super()
问:
注意:部分代码将使用西班牙语。
你好。我为我的 Spring Boot 应用程序制作了一个很好的异常模型,以便我抛出的每个个性化异常都会创建一个个性化响应(在这种情况下,它是一个称为 的类),因此我可以用 捕获该异常,并返回该特定异常创建的异常。在个性化异常中创建的每个异常的特别之处在于 a 和 a .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属性中读取 and,以便可以在运行时更改值而无需重新运行应用程序。这个简单的改变打破了一切。code
description
我开始明白,这工作的唯一原因是因为在我所做的抽象类中,类型“有点已经存在”的字段(在此示例中,这返回“code”)。如果它不是也不是类型,则不起作用,它会在执行构造函数后加载所有内容,因此我最终创建了一个 .此外,必须是构造函数中的第一件事,所以我无法正确初始化变量。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);
}
}
这是行不通的,老实说我不知道该怎么办。
答:
字段初始值设定项直到稍后才会运行。但是,您拥有的这 2 个字段似乎没有任何功能。你不需要它们。充其量,它们的存在是缓存 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);
}
}
这避免了以下问题:没有字段,因此没有字段初始值设定项,因此您不会遇到任何与初始化序列问题有关的问题。
评论
IErrorException
errorModel
errorModel
评论
ErrorModel
super
super(Yml.get("cod"), Yml.get("desc"), errores);
get
Yml
codigo
description
ClienteSinMorasException
private final List<Map<String, String>> errores;