java 显式初始化_为什么局部变量需要显式设置初始化值

作为 java 初学者记录一下, 有问题请多指教.

Why must local variables, including primitives, always be initialized in Java?

首先, 无论堆内还是栈中, 一块内存用完(即堆内成员不再被引用, 栈内方法出栈)后, 并不是说这块内容被清理干净(比如每一位都变为 0), 它的内容并没有变化, 只是被标记为可用状态.

那么, 如果声明一个成员变量或局部变量, 没有初始化(或赋值), 也没有默认值(成员变量有默认值, 这里假设没有), 就可能出现读取到尚未擦除的敏感数据, 带来安全问题. 所以, 解决这个问题就有两种方法:在声明时就给一个默认值, 这样就像成员变量一样;

在你读取内容之前, 就发现你没赋值, 提醒你有错, 强制你赋值, 就像局部变量一样.

那么为什么两个不一样呢? 我认为, 局部变量声明在方法中, 在方法内部, 局部变量的赋值和取值(读取)的顺序是确定的, 编译器是可以检查到读取局部变量之前你有没有给它赋值, 那么既然在编译器这里就能捕获错误, 那何乐而不为呢? 也就是说, 局部变量是可以具有默认值, 但如果编译器可以证明你正在尝试读取未初始化的变量, 就提前纠正你了, 那不更好吗? 所以与其为局部变量提供默认值, 更好的做法是强制你始终为其显式赋值。

但对于成员变量和静态变量来说, 编译器是无法知道调用方法的顺序的. 比如:

public class Test {

public String name;

public void dumpField() {

System.out.println("dumpField name=" + name);

}

}

name 的赋值可以发生在 dumpField() 之前, 也可以发生在 dumpField() 之后. 这是在运行时发生的, 在编译器来看确定不了的. 也就是说一个属性的 setter 和 getter 谁前谁后是不确定的, javac 也不知道, 所以就没办法提醒你是否可能产生错误和危险. 因此, java 就给了成员变量默认值(0, false, null等), 也就是说成员变量至少有一个已知值, 保证就算取值在赋值之前也能读取一个安全值, 这也就消除了读取尚未擦除的敏感数据的潜在安全问题.

References:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值