java - 在 Java Bean 中获取 "last visited field"

标签 java exception reflection javabeans

对于异常处理,我想知道给定 Bean 中的哪个 getter/field 产生了异常。我不想要的是围绕每个 getter 调用进行 try/catch,或者必须手动跟踪字符串变量。

我可以使用 Java Reflections 来实现它吗? 我如何设计 Bean 实现的接口(interface)?

我希望发生异常处理的伪代码:

try {
            step.setNo(Long.parseLong(stepElement.getChildText("no", nameSpace)));
            step.setName(stepElement.getChildText("name", nameSpace));
            step.setDetail(stepElement.getChildText("detail", nameSpace));
            step.setEcuName(stepElement.getChildText("ecu-name", nameSpace));
}catch(Exception e){
            String fieldname = /*which field did throw? */
}

实际 Bean 的一部分:

public class CupProcStep {
    private long no;
    private String name;
    private String detail;
    private String ecuName;
    private String ecuVariant;
    private String diagnosticsId;
    private String errorText;
    private String stepResult;

public long getNo() {
        return no;
    }

    public void setNo(long no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public String getEcuName() {
        return ecuName;
    }

引发异常的字段名称,例如“否”、“名称”、“ecuName”等

最佳答案

反射(reflection)几乎总是错误的解决方案。

在执行可能抛出异常的代码期间存储相关字段名称非常容易。

String fieldName = "no";
try {
    step.setNo(Long.parseLong(stepElement.getChildText("no", nameSpace)));
    fieldName = "name";
    step.setName(stepElement.getChildText("name", nameSpace));
    fieldName = "detail";
    step.setDetail(stepElement.getChildText("detail", nameSpace));
    fieldName = "ecu-name";
    step.setEcuName(stepElement.getChildText("ecu-name", nameSpace));
} catch (Exception exc) { // Be more specific!
    // fieldName available here
}

在这种情况下,我们可以通过只写入一次字段名称来更好地确保不会出现复制粘贴错误。

String fieldName = "no";
try {
    step.setNo(Long.parseLong(stepElement.getChildText(fieldName, nameSpace)));
    fieldName = "name";
    step.setName(stepElement.getChildText(fieldName, nameSpace));
    fieldName = "detail";
    step.setDetail(stepElement.getChildText(fieldName, nameSpace));
    fieldName = "ecu-name";
    step.setEcuName(stepElement.getChildText(fieldName, nameSpace));
} catch (Exception exc) { // Be more specific!
    // fieldName available here
}

有些人会将赋值放在方法调用中 (getChildText(fieldName = "ecu-name",)),但我不喜欢子表达式中的副作用。

整个 stepElement.getChildText(fieldName, nameSpace) 是重复的代码,并且可能对其他类型重复。将其分解到类中作为练习。 try-catch 部分可以使用 Execute around 习惯用法分解出来。这最终会导致客户端代码如下所示:

someObject.someFunction(element -> {
    step.setNo(Long.parseLong(element.get("no")));
    step.setName(element.get("name"));
    step.setDetail(element.get("detail"));
    step.setEcuName(element.get("ecu-name"));
});

或者,我猜:

someObject
    .get("no",       step::setNo, Long::parseLong)
    .get("name",     step::setName)
    .get("detail",   step::setDetail)
    .get("ecu-name", step::setEcuName);

有一些 ORM(对象关系映射)库,例如 JAXB,可用于某些类型的格式,但它们变成了一个令人惊讶的大项目 - 如果可以的话,请使用现有的实现(除非你特别想剃掉那头牦牛的毛) .

关于java - 在 Java Bean 中获取 "last visited field",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58432904/

相关文章:

java - 使用Reflection API是否会使Java的安全性降低?

java - 在java中使用scala列表

java - Java Web 应用及其替代品的二级缓存

php - 在 PHP MVC 应用程序中在哪里捕获异常?

java - 类名可以用作数组的数据类型吗?

java - 如何使用 Javassist 获取原始类型的类?

java - sql中实现双连接

java - 在 Grails 项目中安装插件 jar 吗?

java - PreparedStatement.setQueryTimeout() 不抛出异常

c# - 如何查找类实例的通用属性名称以及如何为属性运行时赋值