试验《Java并发编程实践》3.2的"不要让this在构造期间逸出"

本文深入分析了在Java构造期间this逸出的现象及其可能带来的隐患,通过实例展示了即使构造方法未完全执行,this赋值给其他对象后仍能正常使用,但由此可能引发的数据初始化错误。随后,文章通过修改示例代码,打印出了未完全初始化的this域的默认值,进一步揭示了构造期间对象使用的潜在风险。

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

import java.io.IOException;

public class Demo {

    public Demo(T1 t1){
        t1.demo = this;// 将this在构造期间就逸出,这样逸出的对象被认为是“没有正确构建的(not properly constructed)”
        try {
            Thread.sleep(100000000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void print() {
        System.out.println("demo's method");
    }

    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        T1 t1 = new T1();
        t1.start();
        new Demo(t1);
    }

    static class T1 extends Thread {
        public Demo demo;
        public void run() {
            while (true) {
                if (demo != null) {// 事实证明,即使Demo的构造方法未执行完,this赋值给T1.demo后,不为null
                    demo.print();// 且能够正常使用demo的实例方法。至于由于demo的构造方法未执行完会带来什么不稳定的影响,应该是指它可能未按照预期的去初始化一些数据。
                }
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

 

 

实验表明: this在构造期间(未完成构造)可以逸出,并且看起来使用很正常,但使用“没有构造完全的对象”,会有隐患,这就是书里想说的道理。

 

 

上面的例子,讲述“逸出”的例子,但是它没有展现出“逸出”的危害。

下面将展示“逸出”的危害,它将final域的默认值给打印了出来。

 

import java.io.IOException;

public class Demo {

    final int x;
    public Demo(T1 t1){
        t1.demo = this;// 将this在构造期间就逸出,这样逸出的对象被认为是“没有正确构建的(not properly constructed)”
        try {
            Thread.sleep(100000000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        x=9;
    }

    public void print() {
        System.out.println(this.x);
    }

    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        T1 t1 = new T1();
        t1.start();
        new Demo(t1);
    }

    static class T1 extends Thread {
        public Demo demo;
        public void run() {
            while (true) {
                if (demo != null) {
                    demo.print();
                }
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
 

打印了:

0
0
0
0
0

....

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值