Java中通过方法创建对象的相关技术问题咨询
我有一个关于通过方法创建对象的问题,以下是我的代码:
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()); } }
我曾尝试创建一个每次调用方法时自增的int变量,将其作为对象名的一部分,示例代码如下:
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; }
尝试后发现此方法不可行,之后我又尝试让用户输入字符串作为对象名,同样失败了。现提出以下问题:
- 程序中创建的Student对象的对象名是什么?
- 连续调用createStudent方法创建多个学生对象时,之前的对象会被覆盖吗?
- 如何实现让用户自定义对象名?
1. 程序中创建的Student对象的对象名是什么?
首先要明确:对象本身没有“名字”,你代码里的student只是一个引用变量,它的作用是指向堆内存中实际创建的Student对象。每次调用createStudent方法时,方法内部会创建一个局部引用变量student,指向新的Student对象,方法返回后这个局部变量就会被销毁,但对象本身如果被其他引用(比如你添加到studentArrayList里)持有,就会继续存在。
堆里的每个Student对象,唯一标识是它在内存中的地址,业务上你可以通过对象的name属性来区分不同学生,这才是实际意义上的“学生名字”。
2. 连续调用createStudent方法创建多个学生对象时,之前的对象会被覆盖吗?
不会被覆盖。每次调用createStudent都会通过new Student(...)在堆内存中创建一个全新的Student对象,每个对象都有独立的内存空间和属性值。
你把创建好的对象添加到studentArrayList里,这个集合会持有每个对象的引用,所以之前的对象不会被垃圾回收,也不会被新对象覆盖。你可以看addStudent方法里的循环输出,每次添加后都会打印所有已有的学生信息,这也能证明之前的对象还存在。
3. 如何实现让用户自定义对象名?
Java里无法在运行时动态创建自定义名称的引用变量,这是编译型语言的特性,变量名必须在编译阶段确定。但你可以换一种思路,用Map来关联用户输入的名称和Student对象,这样就能实现类似“用户自定义对象名”的效果:
修改你的代码,比如在main方法里用HashMap:
import java.util.HashMap; import java.util.Scanner; // ... 保留Student类的其他代码 ... public static void main(String[] args){ ArrayList<Student> studentArrayList = new ArrayList<>(); HashMap<String, Student> studentMap = new HashMap<>(); Scanner scanner = new Scanner(System.in); // 第一次创建学生 Student s1 = createStudent(); System.out.println("请输入这个学生的自定义标识名:"); String customName1 = scanner.next(); studentMap.put(customName1, s1); studentArrayList.add(s1); // 第二次创建学生 Student s2 = createStudent(); System.out.println("请输入这个学生的自定义标识名:"); String customName2 = scanner.next(); studentMap.put(customName2, s2); studentArrayList.add(s2); // 测试通过自定义名称获取对象 System.out.println("输入要查询的学生标识名:"); String queryName = scanner.next(); Student queriedStudent = studentMap.get(queryName); if(queriedStudent != null){ System.out.println("查询到的学生:" + queriedStudent.getName() + ",年龄:" + queriedStudent.getAge()); } }
这样用户输入的字符串就相当于这个学生对象的“自定义名字”,你可以通过Map的key来快速找到对应的Student对象,完全能满足你想要的“自定义对象名”的需求。
内容的提问来源于stack exchange,提问作者Jack M

