目录

1.如何初始化对象

2.构造方法

 特性:

3.默认初始化

就地初始化

1.如何初始化对象

在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。要让下面代码通过编译,只需在正式使用a之前,给a设置一个初始值即可。

public static void main(String[] args) {
        int a;
        System.out.println(a);
    }
// Error:(26, 28) java: 可能尚未初始化变量a

如果是对象:

public static void main(String[] args) {
        Date d = new Date();
        d.printDate();
        d.setDate(2021,6,9);
        d.printDate();
    }
//代码可以正常通过编译

需要调用之前写的SetDate方法才可以将具体的日期设置到对象中。通过上述例子发现两个问题:

1. 每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?

2. 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

2.构造方法

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次

注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。

javascrip怎么初始化对象大小 java初始化对象的方法_构造方法

public class DateUtil {
    public int year;
    public int month;
    public int day;

    public DateUtil() {
        System.out.println("不带参数的构造方法!!!这个方法如果没有写,Java会默认提供!");
    }
// 构造方法:
// 名字与类名相同,没有返回值类型,设置为void也不行
// 一般情况下使用public修饰
// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public void setDay(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void show(){
        System.out.println("年:" + year + " 月:" + month + " 日:" + day);
    }

    public static void main(String[] args) {
        //此处创建了一个Date类型的对象,并没有显式调用构造方法
        DateUtil dateUtil = new DateUtil();
        dateUtil.setDay(2022,11,11);
        dateUtil.show();
        DateUtil dateUtil2 = new DateUtil();
        dateUtil.setDay(2022,11,12);
        dateUtil.show();
        DateUtil dateUtil3 = new DateUtil();
        dateUtil.setDay(2022,11,13);
        dateUtil.show();
    }
}

javascrip怎么初始化对象大小 java初始化对象的方法_javascrip怎么初始化对象大小_02

javascrip怎么初始化对象大小 java初始化对象的方法_开发语言_03

 特性:

1. 名字必须与类名相同。

2. 没有返回值类型,设置为void也不行。

3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)。

4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)。

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;
    }
}

javascrip怎么初始化对象大小 java初始化对象的方法_开发语言_04

注意: (1)this(...)必须是构造方法中第一条语句;

(2)不能形成环。

public Date(){
        this(1900,1,1);
    }
public Date(int year, int month, int day) {
        this();
    }
/*
无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
编译报错:Error:(19, 12) java: 递归构造器调用
*/

javascrip怎么初始化对象大小 java初始化对象的方法_jvm_05

javascrip怎么初始化对象大小 java初始化对象的方法_开发语言_06

 

7. 绝大多数情况下使用public来修饰,特殊场景下会被private修饰。

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);
    }
}
Date d = new Date(2021,6,9);

这里简单的一条语句,在JVM层面需要做好多事情:

1. 检测对象对应的类是否加载了,如果没有加载则加载;

2. 为对象分配内存空间;

3. 处理并发安全问题,比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突;

4. 初始化所分配的空间 即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:

javascrip怎么初始化对象大小 java初始化对象的方法_jvm_07

5. 设置对象头信息;

6. 调用构造方法,给对象中各个成员赋值。

就地初始化

在声明成员变量时,就直接给出了初始值。

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();
    }
}

 注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。