本文主要是介绍【Java SE】7.2对象的构造及初始化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1.对象的构造及初始化
1.1如何初始化对象
1.2构造方法
1.2.1概念
1.2.2特性
1.3默认初始化
1.4就地初始化
1.对象的构造及初始化
1.1如何初始化对象
在Java方法内部定义一个局部变量时,必须要初始化,否则编译会失败。
public static void main(String[] args) {
int a;
System.out.println(a);
}
// Error:(26, 28) java: 可能尚未初始化变量a
要让上述代码通过编译,非常简单,只需要在正式使用a之前,给a设置一个初始值即可,如果是对象:
public static void main(String[] args) {
Date d = new Date();
d.printDate();
d.setDate(2021,6,9);
d.printDate();
}
// 代码可以正常通过编译
需要调用之前写的SetDate方法才可以将具体的日期设置到对象当中,通过上述例子发现了两个问题:
1.每次对象创建好后必须要建立SetDate方法设置日期,比较麻烦,那对象如何初始化?
2.局部变量必须进行初始化之后才能正常使用,为什么字段声明之后没有给值依然可以使用?
1.2构造方法
1.2.1概念
构造方法是一个特殊的成员方法,名字必须与类名相同,在创建对象的时候,由编译器自动调用,并且在整个对象的生命周期只调用一次。
public class Date {
public int year;
public int month;
public int day;
// 构造方法:
// 名字与类名相同,没有返回值类型,设置为void也不行
// 一般情况下使用public修饰
// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("Date(int,int,int)方法被调用了");
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
// 此处创建了一个Date类型的对象,并没有显式调用构造方法
Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
d.printDate(); // 2021-6-9
}
}
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
1.2.2特性
- 名字必须和类名相同
- 没有返回值类型,设置void也不行
- 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
- 构造方法可以重载
public class Date {
public int year;
public int month;
public int day;
// 无参构造方法
public Date(){
this.year = 1900;
this.month = 1;
this.day = 1;
}
// 带有三个参数的构造方法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Date d = new Date();
d.printDate();
}
}
上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载。
5.如果用户没有显示定义,编译器一定会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
public class Date {
public int year;
public int month;
public int day;
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
Date d = new Date();
d.printDate();
}
}
上述Date类,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。
注意:一旦用户定义,编译器就不再生成。
public class Date {
public int year;
public int month;
public int day;
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
// 如果编译器会生成,则生成的构造方法一定是无参的
// 则此处创建对象是可以通过编译的
// 但实际情况是:编译期报错
Date d = new Date();
d.printDate();
}
}
/*
Error:(26, 18) java: 无法将类 extend01.Date中的构造器 Date应用到给定类型;
需要: int,int,int
找到: 没有参数
原因: 实际参数列表和形式参数列表长度不同
*/
6.构造方法中,可以通过this调用其他的构造方法来简化代码。
public class Date {
public int year;
public int month;
public int day;
// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
// 但是this(1900,1,1);必须是构造方法中第一条语句
public Date(){
//System.out.println(year); 注释取消掉,编译会失败
this(1900, 1, 1);
//this.year = 1900;
//this.month = 1;
//this.day = 1;
}
// 带有三个参数的构造方法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
注意:
- this(……)必须是构造方法中第一条语句。
- 不能形成环
public Date(){
this(1900,1,1);
}
public Date(int year, int month, int day) {
this();
}
/*
无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
编译报错:Error:(19, 12) java: 递归构造器调用
*/
7.绝大多数情况下使用public修饰,特殊场景下会被private修饰。
1.3默认初始化
在上文提出的第二个问题:为什么局部变量在使用时必须要初始化,而成员变量可以不用呢?
public class Date {
public int year;
public int month;
public int day;
public Date(int year, int month, int day) {
// 成员变量在定义时,并没有给初始值, 为什么就可以使用呢?
System.out.println(this.year);
System.out.println(this.month);
System.out.println(this.day);
}
public static void main(String[] args) {
// 此处a没有初始化,编译时报错:
// Error:(24, 28) java: 可能尚未初始化变量a
// int a;
// System.out.println(a);
Date d = new Date(2021,6,9);
}
}
要搞清楚这个过程,就需要知道new关键字背后的一些事情:
Date d = new Date(2021,6,9);
在程序层面只是简单的一句语句,在JVM层面需要做好多事情,
- 检测对象对应的类是否加载了,如果没加载就加载
- 为对象分配内存空间
- 处理并发问题
- 初始化多分配的空间
即:对象空间被申请好之后,对象中的成员已经设置好了初始值,比如:
数据类型 | 默认值 |
---|---|
byte | 0 |
char | "\u0000" |
short | 0 |
int | 0 |
long | 0l |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |
5.设置对象头信息
6.调用构造方法,给对象中各个成员赋值
1.4就地初始化
在声明变量时,直接给出了初始值
public class Date {
public int year = 1900;
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}
注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。
这篇关于【Java SE】7.2对象的构造及初始化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!