构造函数之创建详细过程与到底有没有返回值
构造方法与类同名,在没有构造函数的情况下,系统会给我们自动创建一个无参构造函数,只是我们看不到,当你创建了构造函数时,系统就不会给你创建无参构造函数。其主要作用分以下两种:
- 类的实列化,对象创建是通过构造方法实现的。
- 创建对象的同时,初始化实例变量的内存空间(给实例变量赋值)。
成员变量之实例变量,属于对象级别的变量,这种变量必须先有对象才能有实例变量。实例变量没有手动赋值的时候,系统默认赋值,那么这个系统默认值是什么时候完成的呢?
是在类加载的时候吗?不是,因为类加载的时候只加载了代码片段,还没来得及创建对象。所以此时实例变量并没有初始化。
实际上,实例变量的内存空间是在构造方法执行过程中完成开辟的,完成初始化的,系统在默认赋值的时候,也是在构造方法中执行过程当中完成的赋值。
实例变量默认值:
byte,short,int,long—0
folat,double—0.0
boolean—false
引用数据类型—null
首先我创建一个Student类
public class Student {
private int sno;
private String name;
private int age;
//无参构造函数
public Student() {
}
//有参构造函数
public Student(int sno, String name, int age) {
this.sno = sno;
this.name = name;
this.age = age;
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
然后创建一个测试类StudentTest类
public class StudentTest {
public static void main(String[] args) {
//创建对象
Student stu1 = new Student();
Student stu2 = new Student();
Student stu3 = new Student();
Student stu4 = new Student(2020004,"HH",19);
//赋值
stu1.setSno(2020001);
stu1.setName("LH");
stu1.setAge(22);
System.out.println("学号:"+stu1.getSno()+" 姓名:"+stu1.getName()+" 年龄:"+stu1.getAge());
//赋值
stu2.setSno(2020002);
stu2.setName("LK");
stu2.setAge(20);
System.out.println("学号:"+stu2.getSno()+" 姓名:"+stu2.getName()+" 年龄:"+stu2.getAge());
//输出stu3信息
System.out.println("学号:"+stu3.getSno()+" 姓名:"+stu3.getName()+" 年龄:"+stu3.getAge());
//输出stu4的信息
System.out.println("学号:"+stu4.getSno()+" 姓名:"+stu4.getName()+" 年龄:"+stu4.getAge());
}
}
运行结果:
你会发现stu3的属性都为默认值,这是为何呢?以及stu1、stu2、stu4的值是如何传过去的呢?
首先不难发现stu1,stu2,stu3都是通过无参构造函数创建的对象,stu4是通过有参构造函数创建的对象。总体图如下:
stu1实现过程图:
Student stu = new Student();
Student就是引用数据类型,stu就是变量名(引用),new运算符,Student()无参构造函数(方法)。首先我们执行的是"="的左边,new Student()这是就会在堆内存中开辟一段内存空间并存放实例对象的属性并给对象属性进行初始化。所以我说这里构造方法中其实有这段代码,只是看不到而已。 this.sno=0;this.name=null;this.age=0;(列如stu3我们创建对象,并没有给它赋值,输出的结果都为初始值。而stu1、stu2是先创建了对象在给其赋值,如果我们在赋值之前输出stu1,stu2你会发现,它们输出的结果都为默认值值,所以在调用无参构造函数的时候,我们就给对象进行了初始化赋予了默认值值,只不过后来再次赋值将初始值给覆盖了。stu4调用的是有参构造函数,这里初始化赋de是指定了初始值,所以输出的初始值就是指定的值而不是默认值。)
public Student() {
/**
* this.sno=0;
* this.name=null;
* this.age=0;
*/
}
目前个人能力范围内的理解之构造函数是否有返回值?
Student stu = new Student();
new Student()是类的实例化,创建了一个学生类的对象,这个对象存储了实例变量(赋予默认值),那么引用变量stu是怎么能够访问到对象中的实例变量呢?对象存储在堆中,引用变量是一个局部变量存储在栈中,stu中存储的是对象的地址,所以stu能指向对象,那么必然new Student()(new 运算符、Student()构造方法)会返回一个"值"(对象在堆中存储的地址),然后赋值给stu。目前个人能力的知识只能这样理解。每一个构造方法实际上执行结束之后都有返回值,但是return 值;这样的语句不需要写,构造方法结束时Java程序会自动返回值。构造方法返回的类型就是类本身Student(构造方法所在类的类型),所以返回值类型也不需要写,如果写了void之类的就是一个普通方法。
等待后续继续学习继续深究没有返回值的构造函数是怎么完成赋值的?
有个例子:String st = new String(“abc”);通过这个解释构造函数到底有没有返回值?