【Java / Kotlin】Warning:Leaking ‘this‘ in constructor of non-final class

博客讨论了在Java和Kotlin中构造函数使用this的警告,指出这可能导致未初始化成员变量被访问,尤其是在多线程环境中。即使在final类中,如果this引用过早暴露,子类构造未完成时,其他线程可能访问到未初始化的成员,引发NullPointerException。建议在排查此类问题时,考虑此类警告并谨慎处理构造函数中的this使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在构造函数(注意:init 块和给成员变量(属性)赋初值的语句,都是构造函数的一部分)中使用 this 时,可能会出现这个警告。如果不理会,可能导致访问到未初始化的成员变量。Java 中,它们可以是未赋初值或赋值为 null 的引用类型;Kotlin 中,可以是 lateinit var 或未赋值或赋值为 null 的可空类型。
事实上,在构造函数中使用 this,即便这个类是 final 的(Kotlin 中则为没有 open 修饰的类),也有可能导致这样的后果。这主要发生在将 this 作为参数(实参)传递给其它函数,或者添加到 Array 之类的情形中。在这些条件下,其它函数可以通过这个引用访问到该类的公有成员。然而,在使用 this 这一行的语句之后,可以还有其它语句;又或者,这条语句是调用了其它函数,在这个被调用的函数里完成了传递 this 引用或将其添加到数组之类的动作。很显然,这一瞬间,构造函数还没有执行完毕(没有返回)。在多线程的条件下,如果其它函数可以使用 this 引用(比如,在添加到 ArrayList 后,就立即通过条件变量的 notify 操作通知其它线程,这些线程继续执行的时候,通过这个引用,访问该类的实例),那么,它们就有可能在该类的实例的构造函数未完成的时候,访问到尚未被初始化的成员,进而 NullPointerException。此外,并不是在构造函数的最后一条语句里才这么做就万事大吉。为了提升性能,语句(指令)的顺序是可以被重排的。也就是说,在函数本体中,最后才出现的语句不一定是最后才被执行的。
如果这个类还有子类,更有可能出现这样的后果。通常,会在子类的构造函数中调用父类的构造函数。父类的构造函数将 this 暴露给其它函数的时候,子类还没有构造完毕。其它函数可以通过这个 this 引用,访问到子类的成员。而这些成员里,自然有可能存在一些尚未初始化的成员。
当然,毕竟这只是一个警告。如果置之不理,还是能通过编译的。假使实在需要这样做,也并不是不行。不过,如果产生了 NullPointerException,且异常点所在的类存在子类,或程序是多线程的;并且涉及的这些类的代码中存在这样的警告,则可以考虑往这个方面排查原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值