【JAVASE】类与对象 下

简介: 【JAVASE】类与对象

5.2.2 特性


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

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

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

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

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

🍤 运行结果:


e0fe9dc03d0e9ee1bdb5026f8f8cf255_c2e32a146aed4e4891ced8ba102734fb.png


注: 一旦用户定义,编译器则不再生成。


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

报错:


618a01b470dd96f93906a5ace93d0094_40b5407fab5b40eb8ebd81252f762213.png


6.构造方法中,可以通过 this 调用用其他构造方法来简化代码。

public class Date {
  public int year;
  public int month;
  public int day;
  // 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
  // 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
  // 但是this(2023,8,1);必须是构造方法中第一条语句
  public Date(){
    //System.out.println(year); 注释取消掉,编译会失败
    this(2023, 8, 1);
    //this.year = 2023;
    //this.month = 8;
    //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();
    }
}

🍤 运行结果:


b34d3cc3d82d7079a0fcc4e856a5c290_0a75d04b317e486f96014e66aac5762a.png


注:


  • this(…)必须是构造方法中第一条语句
  • 不能形成环

例如:


public Date(){
  this(1900,1,1);
}
public Date(int year, int month, int day) {
  this();
}

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


5.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) {
     //int a;
     //System.out.println(a);
    Date d = new Date(2021,6,9);
  }
}

🍤 运行结果:


9b07430c3c530b137308bc723c727fee_73235d0ade3242a19de86e27641d31d9.png


4dad3ea47180cd317e529c54db88aecc_3340e52d0cd44f888cf126a321ae2cd1.png


要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:


Date d = new Date(2021,6,9);

在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:


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

2.为对象分配内存空间

3.处理并发安全问题

比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突

4.初始化所分配的空间

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

数据类型 默认值
byte 0
char ‘\u0000’
short 0
int 0
long 0L
boolean false
float 0.0f
double 0.0
reference null

5.设置对象头信息

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


5.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) {
      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 d1 = new Date(2023,8,1);
        Date d2 = new Date();
        d1.printDate();
        d2.printDate();
    }
}

🍤 运行结果:


53a167524c4a3f501bfb5b4d442776aa_4a9420faa5374c149a1fd3dd9126fbf9.png


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


相关文章
【JavaSE】详解final关键字
【JavaSE】详解final关键字
|
Java 编译器
【JAVASE】类与对象 中
【JAVASE】类与对象
|
存储 Java 编译器
【javaSE】 类和对象详解(下)
【javaSE】 类和对象详解(下)
|
7月前
javaSE&多态
javaSE&多态
37 1
|
安全 Java
【JAVASE】多态 下
【JAVASE】多态
|
存储 安全 Java
类和对象【JavaSE】
类和对象【JavaSE】
80 0
|
Java Android开发
【javaSE】 类和对象详解(上)
【javaSE】 类和对象详解(上)
|
存储 Java Android开发
【JAVASE】类与对象 上
【JAVASE】类与对象
|
Java 编译器
【JAVASE】多态 上
【JAVASE】多态
|
存储 Java 编译器
【JavaSE】类和对象详解(2)
【JavaSE】类和对象详解(2)