在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
要让上述代码通过编译,非常简单,只需在正式使用a之前,给a设置一个初始值即可。
如果是对象:
需要调用之前写的SetDate方法才可以将具体的日期设置到对象中。
//Data类
class Data {public int year;public int month;public int day;public void setData(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public void printData() {System.out.println(this.year + "/" + this.month + "/" + this.day);}
}public class test {public static void main(String[] args) {Data data = new Data();data.printData();data.setData(1998, 9, 18);data.printData();}
}
通过上述例子发现两个问题:
- 每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?
- 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且
在整个对象的生命周期内只调用一次。
class Data {public int year;public int month;public int day;// 构造方法:// 名字与类名相同,没有返回值类型,设置为void也不行// 一般情况下使用public修饰// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次public Data(int year, int month, int day) {this.year = year;this.month = month;this.day = day;System.out.println("调用了一次还有三个参数的构造方法");}public void printData() {System.out.println(this.year + "/" + this.month + "/" + this.day);}
}public class test {public static void main(String[] args) {Data data = new Data(1998, 9, 18);//调用构造方法data.printData();}
}
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
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;System.out.println("调用了一次还有三个参数的构造方法");}//不含参数的构造方法public Date(){this.year = 1900;this.month = 1;this.day = 1;}//三个参数的构造方法和不含参数的构造方法之间形成了重载public void printDate() {System.out.println(this.year + "/" + this.month + "/" + this.day);}
}
例如这里的Date类中有一个三个参数的构造方法 此时如果在创建一个对象但是不传参数则会报错 因为编译器不会再给你创建一个无参数的构造方法 此时必须自己才实现一个无参数的构造方法才还可以继续使用
为什么局部变量在定义时要初始化 而成员变量则可以不初始化呢?
要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:
Date d = new Date(2021,6,9);
在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:
检测对象对应的类是否加载了,如果没有加载则加载
为对象分配内存空间
处理并发安全问题
比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
初始化所分配的空间
即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:
设置对象头信息
调用构造方法,给对象中各个成员赋值
class Date {public int year = 1998;public int month = 1;public int day = 1;//在定义时就初始化public void printDate() {System.out.println(this.year + "/" + this.month + "/" + this.day);}
}