You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Apache Commons HashCodeBuilder排除子类指定字段?

问题原因

HashCodeBuilder.reflectionHashCode的排除字段列表仅作用于当前被反射的类(此处为Car),你传入的version是嵌套类TyreClass的字段,Car类中不存在该字段,因此排除列表无法对其生效。另外你的代码里carObject_2.setVersion(2);是笔误,应该是carObject_2.getTyre().setVersion(2);,否则无法编译。

解决方案

方案1:手动实现哈希码(推荐,可控性更强)

放弃反射,手动编写hashCode方法,明确指定需要参与哈希计算的字段,彻底避免反射的局限性:

// TyreClass的hashCode实现,排除id和version
@Override
public int hashCode() {
    return new HashCodeBuilder(17, 37)
            .append(radius)
            .append(colour)
            .append(width)
            .toHashCode();
}

// Car的hashCode实现,排除id,直接调用TyreClass的自定义hashCode
@Override
public int hashCode() {
    return new HashCodeBuilder(17, 37)
            .append(modelYear)
            .append(color)
            .append(tyre)
            .toHashCode();
}

使用时直接调用对象的hashCode()方法即可,无需依赖反射:

int hashCode_1 = carObject_1.hashCode();
int hashCode_2 = carObject_2.hashCode();

方案2:自定义FieldFilter实现反射过滤

如果必须使用反射,可以通过自定义FieldFilter来递归过滤所有需要排除的字段,包括嵌套类的字段:

// 自定义字段过滤器,指定所有要排除的字段
FieldFilter excludeFilter = (field) -> {
    // 排除Car类的id字段
    if (field.getDeclaringClass() == Car.class && field.getName().equals("id")) {
        return false;
    }
    // 排除TyreClass的id和version字段
    if (field.getDeclaringClass() == TyreClass.class && 
        (field.getName().equals("id") || field.getName().equals("version"))) {
        return false;
    }
    return true;
};

// 调用带过滤器的重载方法,开启递归处理嵌套对象(第三个参数为true)
int hashCode_1 = HashCodeBuilder.reflectionHashCode(17, 37, carObject_1, true, null, excludeFilter);
int hashCode_2 = HashCodeBuilder.reflectionHashCode(17, 37, carObject_2, true, null, excludeFilter);

补充:关于@HashCodeExclude注解

如果你的Apache Commons Lang版本≥3.12,HashCodeBuilder可以识别@HashCodeExclude注解,但需要确保调用的是支持注解的重载方法,且递归处理嵌套对象时注解能被识别。不过相比自定义过滤器或手动实现,注解的灵活性较差,遇到嵌套场景容易出现预期外的问题。

内容的提问来源于stack exchange,提问作者user1416932

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:52:54