【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


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


相关文章
|
SQL 关系型数据库 MySQL
MySQL UPDATE 更新
MySQL UPDATE 更新
|
算法 Java API
Android性能优化面试题经典之ANR的分析和优化
Android ANR发生于应用无法在限定时间内响应用户输入或完成操作。主要条件包括:输入超时(5秒)、广播超时(前台10秒/后台60秒)、服务超时及ContentProvider超时。常见原因有网络、数据库、文件操作、计算任务、UI渲染、锁等待、ContentProvider和BroadcastReceiver的不当使用。分析ANR可借助logcat和traces.txt。主线程执行生命周期回调、Service、BroadcastReceiver等,避免主线程耗时操作
301 3
|
缓存 Java Linux
Maven 仓库
Maven仓库管理构件(JAR, WAR等),包括本地(首次执行Maven时创建,默认在用户目录的\.m2\repository)、中央(社区维护,广泛包含开源Java库,可通过http://search.maven.org/搜索)和远程仓库。若本地仓库缺失构件,Maven会从远程下载并缓存。可修改settings.xml改变本地仓库位置。
|
传感器
stm32f407探索者开发板(二十二)——通用定时器基本原理讲解
stm32f407探索者开发板(二十二)——通用定时器基本原理讲解
1380 0
|
存储 安全 数据安全/隐私保护
安全升级!Python AES加密实战,为你的代码加上一层神秘保护罩
【8月更文挑战第2天】数据安全至关重要,AES加密作为对称加密的标准之一,因其高效性与灵活性被广泛采用。本文通过实战演示Python中AES的应用,使用pycryptodome库进行安装及加密操作。示例代码展示了生成随机密钥与初始化向量(IV)、对数据进行加密及解密的过程。注意事项包括密钥管理和IV的随机性,以及加密模式的选择。掌握AES加密能有效保护敏感数据,确保信息安全无虞。
345 6
|
12月前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
1917 3
|
前端开发 API 微服务
SpringCloud微服务之间使用Feign调用不通情况举例
SpringCloud微服务之间使用Feign调用不通情况举例
1496 2
|
程序员 开发者
IDEA插件-Key Promoter X快捷键显示
Key Promoter X 是一款用于 IntelliJ IDEA 的插件,旨在帮助开发者学习并提键盘快捷键使用效率。它会监视用户在 IDEA 中的操作,并在您使用鼠标执行某些操作时提供相应的快捷键提示。 当使用鼠标点击一个按钮或菜单项时,Key Promoter X 会显示一个弹窗,告诉用户可以使用哪个键盘快捷键来执行相同的操作。
489 0
IDEA插件-Key Promoter X快捷键显示
|
机器学习/深度学习 缓存 运维
智能化运维:机器学习在故障预测与自动修复中的应用
随着信息技术的飞速发展,企业系统日益复杂,传统运维模式面临巨大挑战。智能化运维作为一种新兴趋势,通过集成机器学习算法,实现对系统故障的预测和自动修复,显著提高运维效率与准确性。本文深入探讨了智能化运维的概念、关键技术及其在故障预测和自动修复方面的应用实例,旨在为读者提供一种科学严谨、数据导向的视角,理解智能化运维的价值与实践路径。
445 0
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】47. Pytorch图片样式迁移实战:将一张图片样式迁移至另一张图片,创作自己喜欢风格的图片【含完整源码】
【从零开始学习深度学习】47. Pytorch图片样式迁移实战:将一张图片样式迁移至另一张图片,创作自己喜欢风格的图片【含完整源码】