Java重写LandTract类equals方法后对象比较始终返回true的排查
代码逻辑异常的根因与修复方案
核心异常根因
- 成员变量被错误修饰为
static:类中定义的length、width、area全部是类级别的静态变量,会被所有LandTract对象共享,不存在每个对象独立存储属性值的能力。后续不管创建多少个对象,所有对这三个变量的赋值操作都会覆盖同一块内存的数值,最终所有对象读到的属性值都是最后一次写入的内容,自然永远满足相等判断的条件,无法触发false分支。 - 派生属性冗余存储:
area是由length * width计算得到的派生值,不需要单独定义成员变量存储。当前代码中area只有在调用getArea()方法时才会被更新,其他场景下可能存在脏值,干扰判断。 - equals方法实现不规范:没有做入参的非空校验、类型校验,强制类型转换容易触发运行时异常;浮点数直接用
!=比较,容易因为精度问题出现判断偏差。 - 三参构造方法逻辑错误:传入参数后没有给成员变量赋值,反而硬编码把变量设为0,完全不符合构造方法的初始化逻辑。
具体修复操作
- 删除所有成员变量的
static修饰符,将length、width调整为类的实例变量,为每个对象分配独立的属性存储空间;移除单独定义的area成员变量,改为在调用getArea()方法时实时计算面积值。 - 清理逻辑无效的三参构造方法,确保两参构造方法正确将传入参数赋值给当前实例的属性。
- 重写
equals方法,增加入参合法性校验,浮点数比较时设置合理的误差阈值(如1e-6),替代直接的不等号比较,避免浮点精度问题。 - 清理main方法中直接对类静态变量赋值的冗余逻辑,将用户输入的数值直接传入
LandTract构造方法完成对象初始化。
修复后关键代码示例
import java.util.Scanner; public class LandTract { // 实例变量,每个对象独立存储 private double length; private double width; public LandTract(double length, double width) { this.length = length; this.width = width; } public double getArea() { return this.length * this.width; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; LandTract land = (LandTract) o; // 浮点数带阈值比较 return Math.abs(this.length - land.length) < 1e-6 && Math.abs(this.width - land.width) < 1e-6; } public static void main(String[] args) { Scanner key = new Scanner(System.in); System.out.print("Enter the length of the first tract of land: "); double firstLength = key.nextDouble(); key.nextLine(); System.out.print("Enter the width of the first tract of land: "); double firstWidth = key.nextDouble(); key.nextLine(); LandTract land1 = new LandTract(firstLength, firstWidth); System.out.println("The area of the first tract of land is " + land1.getArea()); System.out.println(); System.out.print("Enter the length of the second tract of land: "); double secondLength = key.nextDouble(); key.nextLine(); System.out.print("Enter the width of the second tract of land: "); double secondWidth = key.nextDouble(); key.nextLine(); LandTract land2 = new LandTract(secondLength, secondWidth); System.out.println("The area of the second tract of land is " + land2.getArea()); System.out.println(); if (land1.equals(land2)) System.out.println("Both tracts of land are the same size."); else System.out.println("They are different sizes."); } }
内容的提问来源于stack exchange,提问作者Timothy Nguyen
相关产品推荐
相关产品推荐

