向列表添加this时为何触发this-escape警告?
关于this-escape警告的原因及解决办法
警告出现的核心原因
当内部类B不是final时,它允许被继承。假设存在B的子类C,创建C实例时,JVM会先调用父类B的构造方法。此时B的构造里把this(实际是未完成初始化的C实例)添加到A的all_my_Bs列表中。如果此时有其他代码提前访问这个C实例,就可能访问到还没初始化完成的成员变量或方法,引发不可预料的错误。
而把B设为final后,它无法被继承,也就不存在子类未初始化就被暴露的风险,所以编译器会消除这个警告。
不把B设为final的解决办法
把添加实例到列表的操作从构造方法中移出,改用工厂方法来创建B实例:
public class wtf { public static class A { public class B { // 构造方法仅做初始化,不对外暴露this private B() {} } public java.util.ArrayList<B> all_my_Bs = new java.util.ArrayList<B>(); // 工厂方法创建B并加入列表 public B createB() { B b = new B(); all_my_Bs.add(b); return b; } } };
这样一来,只有当B实例完全初始化完成后,才会被添加到列表中,从根源上避免了this逃逸的问题,同时也不用把B设为final。
内容的提问来源于stack exchange,提问作者Don Hatch
相关产品推荐
相关产品推荐

