在自己的构造函数中使用对象

时间:2017-07-19 13:09:27

标签: java constructor

在它自己的构造函数中使用对象是否可能(或者是明智的)?(对于制作不当的noob问题抱歉)

假设我有一个“学生”类,其中包含子类Student的arrayList和一个将新学生添加到数组的方法。

我可以在我的Student构造函数中使用addStudent方法在创建时将新实例添加到数组中吗?...就像这样:

//Students
class Students{
  private static ArrayList<Student> STUDENTS = new ArrayList<>();
  public static void addStudents(Student student){
    STUDENTS.add(student);
  }
}
//Student
class Student /*extends Students <- old misstake left for reference*/{
  private String name = "";
  private int birthYear = 0;

  Student(String _name, int _birthYear){
    this.name = _name;
    this.birthYear = _birthYear;
    //insert wild guess
    Students.addStudents(this(name,birthYear));
  }
}

或者这会简单地循环并创建大量对象,直到一切崩溃?

2 个答案:

答案 0 :(得分:6)

你可以;你不应该。

一个原因是您可能并不总是希望将所有Student个实例添加到同一个共享列表中。例如,如果您在单元测试中创建Student个实例,并将它们添加到构造函数的Students列表中,则必须担心在测试后清除列表,以避免意外在测试之间共享状态。

另一个原因是在构造函数中添加实例称为 unsafe publication 。您正在提供对尚未完全初始化的实例的引用。这可能会导致一些非常棘手的错误,尤其是与并发相关的错误。

您应该等到实例完全初始化(即一个new Whatever已经返回),然后再对其进行任何操作。

您最好将创建Student与添加到Students列表进行脱钩。使用工厂方法创建学生:

class Students{
  private static ArrayList<Student> STUDENTS = new ArrayList<>();
  public static void addStudents(Student student){
    STUDENTS.add(student);
  }

  // Factory method.
  public static Student createAndAddStudent(String name, int birthYear) {
    Student student = new Student(name, birthYear);
    addStudents(student);
    return student;
  }
}

就您当前的代码而言,您不需要extends Students。逻辑上,Student不是Students,只有Car不是Cars(大声说出来;它只是没有意义)

您需要做的就是调用静态方法:

class Student {
   Student() {
     // ...
     Students.addStudents(this);
     // ...
   }
}

答案 1 :(得分:1)

您错误地使用了关键字this。您不会随this一起发送任何值。 this是对当前对象的引用。

使用这种方式的好处是,您永远不必将所有学生单独添加到列表中。除此之外,它将为您省去意外忘记添加一个阵列的麻烦。

class Student extends Students{
    private String name = "";
    private int birthYear = 0;

    Student(String _name, int _birthYear){
        this.name = _name;
        this.birthYear = _birthYear;

        addStudents(this);
    }

    public static void main(String[] args){
        Student s = new Student("Ryan", 1999);
    }
}