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

Foo类applyReplacement返回null:如何避免新建实例获取替换值?

解决Foo类applyReplacement返回null的问题

嘿,我一眼就揪出问题所在了——你的代码里有两个关键bug:一个是equals方法逻辑写错了,另一个是applyReplacement里没必要地新建Foo实例,这俩凑一起直接导致你永远拿不到想要的FooExpression。

问题根源拆解

先看你当前的applyReplacement代码:

@Override 
public FooExpression applyReplacement(Replacement r) { 
    Foo foo = new Foo(name); 
    FooExpression e = r.get(foo); 
    return e; 
}

你在这里新建了一个和当前实例同名的Foo对象,但其实完全没必要——直接用当前对象this去查询就好。不过更致命的是你的equals方法:

@Override 
public boolean equals(Object o) { 
    if (!(o instanceof Foo)) { 
        return false; 
    } else { 
        return name.equals(o); 
    } 
}

这里你把String类型的name直接和Foo对象o做比较,这肯定返回false啊!HashMap查询时会先比对hashCode(你的hashCode逻辑是对的),再用equals确认匹配性,结果equals永远不成立,自然返回null。

具体修复步骤

1. 修正equals方法的逻辑

正确的equals应该先把传入对象转成Foo类型,再比较两个实例的name字段,还要考虑name为null的情况避免空指针:

@Override 
public boolean equals(Object o) { 
    if (!(o instanceof Foo)) { 
        return false; 
    } 
    Foo otherFoo = (Foo) o; 
    // 处理name为null的边界情况
    return name != null ? name.equals(otherFoo.name) : otherFoo.name == null; 
}

对应的hashCode也可以优化下,避免name为null时出错:

@Override 
public int hashCode() { 
    return name != null ? name.hashCode() + 41 : 41; 
}

2. 简化applyReplacement方法,移除多余的实例创建

直接用当前对象this作为key去查询Replacement的map,完全不需要新建Foo实例:

@Override 
public FooExpression applyReplacement(Replacement r) { 
    // 直接用当前实例查询,省掉无意义的对象创建
    return r.get(this); 
}

验证示例

假设你这么使用代码:

// 创建Foo实例
Foo myFoo = new Foo("demo");
// 创建对应的FooExpression实现类实例
FooExpression myExp = new ConcreteFooExpression(); // 替换成你的实际实现类
// 存入Replacement
Replacement replacement = new Replacement();
replacement.put(myFoo, myExp);
// 调用applyReplacement,现在就能正确拿到myExp了
FooExpression result = myFoo.applyReplacement(replacement);

这样修改后,你就不会再拿到null了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:07:28