我似乎无法弄清楚为什么当我清楚地覆盖了相等方法时我总是变得真实

I can't seem to figure out why I keep getting true when I clearly overridden the equality method

我正在尝试解决这个问题,但我似乎无法正确比较它。

每当我 运行 尝试设置代码时,当我也需要它来生成错误测试时,结果最终会变为 True。广泛的测试表明它始终为真,我不知道如何在其上产生假。

import java.util.Scanner;

public class LandTract
{
    // instance variables
    private static double length , width, area;

    /**
     * Constructor for objects of class LandTract
     */
    public LandTract(double length, double width, double area)
    {
        // initialise instance variables
        length = 0;
        width = 0;
    }

    public LandTract(double length, double width)
    {
        this.length = length;
        this.width = width;
    }
    
    public void setLength(double length)
    {
        this.length = length;
    }
    
    public double getLength()
    {
        return length;
    }
    
    public void setWidth(double width)
    {
        this.width = width;
    }
    
    public double getWidth()
    {
        return width;
    }
    
    public double getArea()
    {
        return area = length * width;
    }
    
    public String toString()
    {
        String str = "Length: " + length + "\nWidth: " + width;
        return str;
    }
    
    public boolean equals(Object obj)
    {
        LandTract land = (LandTract) obj;
        if (this.length != land.length)
            return false;
        if (this.width != land.width)
            return false;
        if (this.area != land.area)
            return false;
        
            return true;
    }
    
    public static void main(String[] args)
    {
        Scanner key = new Scanner(System.in);
        
        System.out.print("Enter the length of the first tract of land: ");
        length = key.nextDouble();
        key.nextLine();
        System.out.print("Enter the width of the first tract of land: ");
        width = key.nextDouble();
        key.nextLine();
        LandTract land1 = new LandTract(length , width);
        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: ");
        length = key.nextDouble();
        key.nextLine();
        System.out.print("Enter the width of the second tract of land: ");
        width = key.nextDouble();
        key.nextLine();
        LandTract land2 = new LandTract(length, width);
        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.");
    }
}

令人困惑且具有讽刺意味的错误评论的最佳示例:

// instance variables
private static double length , width, area;

当您:

时,该程序运行得更好:
  1. (真的)引入实例变量:

    private double length , width, area;
    
  2. 修复 main 方法中的编译器问题(通过声明具有相同标识符的局部变量..风格不佳但速度很快):

    public static void main(String[] args) {
       double length, width;
       // ...
    }
    

这里的问题是被比较的值(lengthwidtharea)是静态字段,而不是实例字段。这意味着对它们的任何引用都将使用相同的全局值,无论 class 的哪个实例引用它们。

特别重要的是,equals 方法中的 this.length != land.length 将始终 return true,因为 this.lengthland.length 都将引用到相同的值。 (请注意,如果涉及多个线程,则此保证不再成立,但此示例不是这种情况。)

这也意味着对构造函数或 setter 的任何调用都将设置共享静态字段,覆盖先前在另一个实例上调用 setter 或构造函数时写入的值。例如,length, width 构造函数将覆盖静态 lengthwidth 字段,而 setLength 方法将覆盖静态 length 字段。

public LandTract(double length, double width)
{
    this.length = length;
    this.width = width;
}

public void setLength(double length)
{
    this.length = length;
}

解决方法是将这些字段更改为实例字段,而不是静态字段:

public class LandTract
{
    private double length, width, area;

    // [...]
}