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
相关产品推荐
相关产品推荐

