构造方法尝试从子类获取初始化实例变量获取StackOverflowError

时间:2014-10-15 11:28:57

标签: java inheritance constructor

我需要在Person中填写用户,因为在DB中是必需的,但User是Person的子项,我得到了java.lang.StackOverflowError

用户是一个人 人有一个用户

我知道这是一个递归问题,但我保存了User in Person以了解谁创建了那个人。

我认为这是一个设计问题,但如何解决这个问题呢? 我想为此保存一个默认值,因为数据库需要该字段。

班级人员

public class Person {
  private long idPerson;
  //mandatory field in database
  private User useredt;
  public Person() {
    useredt = new User("test");
  }
  ...
}

班级用户

public class User extends Person {
  private String username;
  private String password;
  private Boolean enabled = false;

  public User() {
  }
  ...
}

失败追踪

java.lang.StackOverflowError
    at sun.util.calendar.ZoneInfo.getOffsets(Unknown Source)
    at sun.util.calendar.ZoneInfo.getOffsets(Unknown Source)
    at java.util.GregorianCalendar.computeFields(Unknown Source)
    at java.util.GregorianCalendar.computeFields(Unknown Source)
    at java.util.Calendar.setTimeInMillis(Unknown Source)
    at java.util.GregorianCalendar.<init>(Unknown Source)
    at java.util.Calendar.createCalendar(Unknown Source)
    at java.util.Calendar.getInstance(Unknown Source)
    at com.javalabs.web.dao.Person.<init>(Person.java:56)
    at com.javalabs.web.dao.User.<init>(User.java:72)
    at com.javalabs.web.dao.Person.<init>(Person.java:60)
    at com.javalabs.web.dao.User.<init>(User.java:72)

5 个答案:

答案 0 :(得分:4)

你有无限递归

new User()隐式调用Person()(超类构造函数),您再次调用new User()再调用Person(),依此类推。

PS:从设计的角度来看,如果用户(继承)的人,那么我认为使用 has-a (组合)用户。

答案 1 :(得分:0)

你期待什么?您在构造函数调用中创建了无限递归。

您可以通过不在Person构造函数中创建User实例来解决此问题。相反,调用一个可以赋值的setter方法。

答案 2 :(得分:0)

是的,这是编码错误的结果。你必须再想一想。在您当前的代码中产生无限递归。

答案 3 :(得分:0)

因为User是Person的子类,所以每个用户也有一个User(有一个User,ad无限) - 这可能不是你想要的。我不确定你想要实现什么,但是在构造函数中设置的Person中有一个User属性是行不通的。

答案 4 :(得分:0)

正如其他人所指出的那样,递归是由Person构造函数创建User类的实例引起的。 User构造函数隐式调用Person构造函数,并使用编译器自动添加的隐式“super()”。所以它进入了一个无限循环。

您必须设计代码以避免此问题。

Person和User类是存储在数据库中的同一个表中,还是存储在单独的表中?

如果User和Person类存储在数据库的同一个表中,并且“User userdt”列不可为空,那么这意味着某些用户/个人记录必须指向自己。这告诉我User类的构造函数需要以“super(this);”开头。行,表示此人的用户本身就是此用户/个人。 Person类的构造函数需要一个“User”参数。

如果User和Person是两个单独的表,那么为什么要让User类扩展Person类?好吧,假设这是你想要的,解决方案仍然与上面相同。