类的默认初始化

为什么局部变量在使用时必须要初始化,而成员变量可以不用呢?
要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:

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

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

  1. 检测Dog的类是否加载JVM了,如果没有加载则加载
    JVM运行起来会加载成千上万个类,也有很多类不是立即加载
    程序中可能会自定义很多的类,这些类不是程序一开始就加载的,而是用谁加载谁
  2. 执行关键字new,看到new就在堆开辟空间。为对象在堆上开辟空间。到底开辟多大内存,就看着各类成员属性的类型以及个数来确定
  3. 调用构造方法 为每个成员属性赋初始值!
    构造方法就是在产生对象时给对象赋值的!
    类中变量都有默认值,默认值是其数据类型的默认值
  4. 处理并发安全问题
    比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
    注意 构造方法就是为成员变量赋值的,因此构造方法也可以重载,重载只是参数的个数不同
    为什么构造方法的重载与类型无关?
    因为我们之前定义过了,我们只是决定不同的构造方法给那些属性赋值而已!
    无参构造都是默认值,一个都不赋值
    有参构造就根据参数的个数来决定赋值那几个成员变量

初始化所分配的空间

即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:
数据类型------------------- 默认值
byte------------------------------ 0
char --------------------------‘\u0000’
short----------------------------- 0
int-------------------------------- 0
long----------------------------- 0L
boolean---------------------- false
float --------------------------0.0f
double -----------------------0.0
reference ----------------------null
就地初始化
在声明成员变量时,就直接给出了初始值。

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

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

### 概念 - **默认初始化**:在创建对象或定义成员变量时,系统会自动为其赋予默认值。对于成员变量,编译器会在对象内存分配后自动赋初值,如 `int` 默认是 0,`boolean` 默认是 `false`,对象引用默认是 `null` 等。在 Java 中,成员变量定义 `String s;` 等同于 `String s = null;`,而本地变量(方法变量)不会自动初始化[^2][^3]。例如: ```java public class DefaultInitializationExample { int num; // 默认初始化为 0 boolean flag; // 默认初始化为 false String str; // 默认初始化为 null public static void main(String[] args) { DefaultInitializationExample obj = new DefaultInitializationExample(); System.out.println(obj.num); System.out.println(obj.flag); System.out.println(obj.str); } } ``` - **显式初始化**:是指程序员在代码中明确地为变量赋予初始值。成员变量的显式初始化可以在声明时直接赋值,也可以通过静态代码块(针对静态变量)、实例初始化块或构造方法来实现;本地变量必须显式赋值后才能使用。在对象实例化时,会先进行默认初始化,然后进行显式初始化和实例初始化块操作,最后执行构造方法体中的代码[^1][^4]。例如: ```java public class ExplicitInitializationExample { int num = 10; // 声明时显式初始化 static int staticNum; static { staticNum = 20; // 静态代码块显式初始化静态变量 } { num = 15; // 实例初始化块显式初始化成员变量 } public ExplicitInitializationExample() { num = 25; // 构造方法显式初始化成员变量 } public static void main(String[] args) { ExplicitInitializationExample obj = new ExplicitInitializationExample(); System.out.println(obj.num); System.out.println(staticNum); } } ``` ### 区别 - **赋值方式**:默认初始化是系统自动完成的,不需要程序员干预;显式初始化是程序员在代码中手动为变量赋值。 - **作用范围**:默认初始化适用于成员变量,本地变量不会进行默认初始化;显式初始化既可以用于成员变量,也必须用于本地变量。 - **执行顺序**:在对象初始化过程中,默认初始化先于显式初始化执行。 ### 应用 - **默认初始化**:可以确保成员变量在使用前有一个初始值,避免因未初始化而导致的运行时错误。例如,在创建对象时,对于一些不需要立即赋值的成员变量,系统会自动赋予默认值,保证程序的基本正确性。 - **显式初始化**:可以根据具体需求为变量赋予合适的初始值,使程序的逻辑更加清晰和可控。例如,在开发一个游戏时,角色的初始生命值、攻击力等属性可以通过显式初始化来设置;对于一些常量或需要特定初始值的静态变量,也会使用显式初始化
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值