javamethodsobject-construction

Using a method to create objects


I have a question regarding creating object using a method, please see my code below:

import java.util.ArrayList;
import java.util.Scanner;

public class Student {
    private String name;
    private int age;
    private double avgTestScore;

    // Getters
    public String getName(){ return this.name; }
    public int getAge(){ return this.age; }
    public double getAvgTestScore(){ return this.avgTestScore; }

    // Setters
    public void setName(){ this.name = " "; }
    public void setAge(){ this.age = 0; }
    public void setAvgTestScore(){ this.avgTestScore = 0.0; }

    //Constructor
    public Student(String name, int age, double score){
        this.name = name;
        this.age = age;
        this.avgTestScore = score;
    }

    public static Student createStudent(){
        Scanner scanner = new Scanner(System.in);

        System.out.println("Please enter the student name");
        String studentName = scanner.next();

        System.out.println("Please enter the student age");
        int studentAge = scanner.nextInt();

        System.out.println("Please enter the student score average");
        double studentScore = scanner.nextDouble();
        
        Student student = new Student(studentName, studentAge, studentScore);
        return student;
    }

    public static void addStudent(ArrayList<Student> list, Student student){
        list.add(student);
        for (Student i : list){
            System.out.println(i.name);
            System.out.println(i.age);
            System.out.println(i.avgTestScore);
        }
    }

    public static void main(String[] args){
        ArrayList<Student> studentArrayList = new ArrayList<>();
        Student.addStudent(studentArrayList, createStudent());
        Student.addStudent(studentArrayList, createStudent());



    }
}

I tried to create an int variable that would increase everytime the method is called and use that as part of the object name, for example:

public static Student createStudent(){
        **int identif = 0;**

        Scanner scanner = new Scanner(System.in);

        System.out.println("Please enter the student name");
        String studentName = scanner.next();

        System.out.println("Please enter the student age");
        int studentAge = scanner.nextInt();

        System.out.println("Please enter the student score average");
        double studentScore = scanner.nextDouble();
        
        Student student+**identif** = new Student(studentName, studentAge, studentScore);
        identif++;
        return student;
    }

After I tried this I realised how stupid I was being. After, I tried to allow the user input a String using the scanner and use that as object name, also didn't work.

My questions:

TIA 😊


Solution

  • To clarify your query, it seems you are referring to "variable name" when mentioning "object name". In java you cannot create a dynamically calculated variable name. The question is why would you want to do so? If you need to store multiple objects and be able to access them by some value (let's say a string), then you may use a Map<>, like @Malz pointed out. For example:

    int identifier = 0;
    final String keyPrefix = "Student";
    
    Map<String, Student> studentMap = new HashMap<>();
    
    studentMap.put(keyPrefix + identifier++, createStudent());
    

    Then, you can access the object by calling:

    studentMap.get("Student0");
    

    Of course if you don't need to use String as a key, then it is better to use just Integers to avoid string concatenation.

    Now, answering your questions directly:

    When a student object is created in my programme, what would the object name be?

    If you don't override the toString() method, the object name would be className@randomHash if the Student is an outer class. So, for example, this is a sample string that would be printed if you used the toString() method on Student, or if you pass a student object to System.out.println() method (the toString() method is then called implicitely): Student@378fd1ac.

    If I create consecutive students using the method, does each previous student object get overwritten?

    Yes, if you create a single variable, let's say Student student, and then assign different objects to it, then the previous object gets overwritten. If you don't have any pointer to that object (i.e., you cannot access it from any other variable), then the object will get automatically garbage collected after some time.

    Student student = createStudent();
    student = createStudent(); //the first student object is not accessible anymore, so it is going to be garbage collected.
    

    How do I allow the user to choose the name of the object.

    Let's clarify the terminology:

    Student student = new Student()
    /\                    /\
    ||                    ||
    variable              object
    

    You may have a single variable pointing to different objects over time. The variable has its name and it cannot be changed. The object, on the other hand, may have a name, as you call it. It is just a String that is returned by the toString() method. The method is called implicitly when you try to print the object to the console, concatenate a string to it etc. For example having such class:

    class Student {
        private final String name;
    
        Student(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Student " + name;
        }
    }
    

    The System.out.println(new Student("Mark")) would yield Student mark