Java静态代码与构造方法

最近在看高翔龙的《Java虚拟机精讲》,在类加载相关章节看到一段例程,很有意思,就此想到一些静态代码和构造方法的问题。

代码类似于:

public class TestClassLoad {

    public static TestClassLoad obj = new TestClassLoad(); //line1
    public static int value1;
    public static int value2 = 0; // line2

    public TestClassLoad() {
        value1 = 10;
        value2 = 10;
        System.out.println("before value1 - " + value1);
        System.out.println("before value2 - " + value2);
    }

    public static void main(String[] args) throws Exception {
        System.out.println("after value1 - " + value1);
        System.out.println("after value2 - " + value2);
    }
}

这段代码的问题在于line1/line2这两行的先后顺序如果不同,会使value2的值不同。line1在前,Value2为0,反之10。原因在于类的加载过程分为加载、链接、初始化三部分,line1和line2属于初始化的逻辑,在此过程中value2被赋值两次。在初始化的时候,由于先后顺序不同,value2最终的值亦不同。从这段代码来看,更可能的意图是希望value2的值为10,但不幸的是最终为0。

由此想到,对于一个Java类,静态代码属于类加载过程处理的,是交给JVM的。构造方法服务于实例化。一个类的加载和实例化是两个截然不同的过程,可能类加载之后,永远不需要实例化。所以,我觉得比较好的编程风格应该是构造方法中处理属于对象特有的数据;而静态的部分属于类共用,最好不要放在构造方法中处理,以免出现前面这个问题。这个问题有一定的隐藏性,尤其在大的工程中,一个java类可能会被无数的人修改,并且存活相当长的时间,如果真遇到类似问题,不一定易于排查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值