1

可能重复:
为什么我收到 StackOverflowError

我正在使用两个课程:日期和考试。Date 从三个整数中设置一个 Date 对象:日、月、年;Exam 从一个 String courseName 和一个 Date 对象中设置一个 Exam 对象。

我正在尝试运行此代码:

    public Exam(String name, Date d)
    {
        courseName=name;
        examDate=new Date(d);
    }

    //**a method that checks if two dates are equal**
    public boolean equals (Date r)
    {
        return (examDate.equals(r));
    }

    public static void main(String[] args)
    {
        Date d=new Date(11,11,2011);
        String a=new String("OOP");
        Exam b=new Exam(a,d);
        Date c=new Date(11,11,2011);
        System.out.println(b.equals(c));
    }

当我尝试运行代码时,线程“main”中出现错误异常java.lang.StackOverflowError

该错误表明问题出在 Date 类中的一行上,该类检查两个日期是否相等:

public boolean equals (Date d)
{
    return (this.equals(d));
}

我会很感激知道为什么会这样。

4

2 回答 2

5
boolean equals(Date d) {
  this.equals(d); 
}

不管这个类是什么,equals 方法都是完全错误的——它只是调用自己,而后者又调用自己,而后者又调用自己,无限递归,直到你得到一个 StackOverflowError。

首先:覆盖equals的正确签名是:

boolean equals(Object obj)

具有特定于类的覆盖只是......奇怪。看起来可能有人试图委托给默认的 equals() 方法,但这不是要做的。

如果这是一个自定义 Date 类,equals 应该类似于:

boolean equals(Object obj) {
  if (!obj instanceof Date) {
    return false;
  }
  Date other = (Date) obj;
  return this.field1.equals(date.field1) && this.field2.equals(date.field2)...... ;
}

另外,现在就在你实现 equals() 的任何时候实现 hashCode 的实践。它将为您节省悲伤。

当我覆盖 equals() 方法时,为什么要覆盖 hashCode()?

于 2013-01-05T18:28:34.117 回答
2

正如詹姆斯所说,return (this.equals(d));绝对是错误的。假设您的Date班级具有年、月和日的属性,您应该尝试类似

public boolean equals(Object o) {
    if (! o instanceof Date) return false;
    Date d = (Date)o;
    return this.year == d.year && this.month == d.month && this.day == d.day;
}

请注意,参数的静态类型很重要Object,请参阅 James 的答案

于 2013-01-05T18:31:57.977 回答