3

Is it possible (or sensible) to use an object in it's own constructor?(Sorry for the poorly formulated noob question)

Say I have a class "Students" which contains an arrayList of subclass Student and a method for adding new students to the array.

Can I in my Student constructor use the addStudent method to add the new instance to the array on creation?... like so:

//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));
  }
}

Or will this simply loop and create a lot of objects until everything crashes?

6
  • 1
    Whats the point in making STUDENTS static? Also, don't make it all capitalized unless it is a static final variable. Commented Jul 19, 2017 at 13:10
  • 1
    What happened when you ran this code ? Commented Jul 19, 2017 at 13:10
  • 3
    Student extends Students sounds weird . Commented Jul 19, 2017 at 13:11
  • 1
    You can change addStudents(this(name,birthYear)); to addStudents(this); if you want to add the new Student to the static List. Commented Jul 19, 2017 at 13:11
  • 3
    Student should not extend Students. A student is not a kind of students. Commented Jul 19, 2017 at 13:11

2 Answers 2

6

You can; you just shouldn't.

One reason is that you might not always want to add all Student instances to the same shared list. For example, if you're creating Student instances in a unit test, and adding them into the Students list in the constructor, you then have to worry about clearing the list after the test, to avoid accidentally sharing state between tests.

Another reason is that adding the instance in the constructor is called unsafe publication. You are giving out a reference to an instance which has not been fully initialized. This can lead to some very tricky bugs, especially related to concurrency.

You should always wait until an instance has been fully initialized (i.e. one new Whatever has returned) before you do anything with it.

You would be better decoupling creating the Student from adding to the Students list. Use a factory method to create 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;
  }
}

In terms of your current code, you don't need extends Students. Logically, Student isn't a Students, any more than a Car wouldn't be a Cars (say it out loud; it just doesn't make sense).

All you need to do is to invoke the static method:

class Student {
   Student() {
     // ...
     Students.addStudents(this);
     // ...
   }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Great answer, told me everything I needed, gave me an example of improvment, cheers!
1

You are using the keyword this incorrectly. You don't send any values along with this. this is a reference to the current object.

The benefit of using this way is that you'll never had to individually add all of the students to a list. Along with this it will save you the hassle of accidentally forgetting to add one to your array.

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);
    }
} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.