Java类实例化自动初始化:为何未赋值的sueldo调用getSueldo()不报错且返回0
这一现象的本质是Java对不同作用域的变量设置了完全不同的初始化规则
两类变量的初始化要求差异
- 写在方法、局部代码块里的局部变量:没有内置的默认初始化机制,编译阶段会做全路径静态检查,如果变量未被显式赋值就被读取,会直接抛出编译错误——这就是日常开发中最常碰到的“变量未初始化”报错的来源。
- 写在类体里、没有
static修饰的实例成员变量:这类变量存在固定的默认初始化逻辑,不受“未赋值不能读取”的编译检查约束,哪怕构造方法里没有显式给它赋值,也会有合法的初始值。
sueldo字段被自动赋值为0的底层执行逻辑
Java语言规范对实例字段的默认值做了明确的强制规定:对象在堆内存完成分配后、任何构造方法逻辑执行前,会对所有实例字段统一做清零赋值,各类型的默认值是完全固定的:
- 所有基本数值类型(
byte/short/int/long/float/double)的默认值是对应精度的0,你代码里的sueldo是double类型,默认值就是0.0,和你观察到的运行结果完全匹配 boolean类型的默认值为false- 所有引用类型(比如代码里的
String、Date)的默认值为null
JVM创建类实例的执行顺序是严格固定的:
- 遇到
new关键字时,先在堆内存为目标类实例划分足够的连续内存空间,空间大小由类定义的所有字段总长度决定 - 对这块刚分配的内存做整体清零,完成所有字段的默认值填充——这一步远早于你写的构造方法逻辑的执行
- 依次执行父类构造逻辑、当前类的实例初始化块、字段显式赋值语句,最后才轮到你自定义的构造方法里的赋值代码生效
回到你贴的代码,当调用单参构造Empleado_test3(String nombre)创建实例时,虽然构造逻辑里只给nombre字段显式赋了值,但sueldo字段在内存分配阶段就已经被自动置为0.0,所以后续调用getSueldo()可以正常拿到这个合法值,既不会触发编译错误,也不会出现运行时异常。
补充:代码中的
altaContrato字段在单参构造创建的实例中同样没有被显式赋值,它的实际值是引用类型对应的默认值null,同样是默认初始化规则生效的结果。
内容的提问来源于stack exchange,提问作者José Marín Sánchez
相关产品推荐
相关产品推荐

