关于java的类实例化的先后顺序

      最近有同事在部署一个旧系统的时候遇到问题,在本地部署是没事的,但一到正式线上服务器就报错。报错的大概意思就是某个类里面的一个静态变量为空导致出现空指针异常。为了帮忙解决这个问题,我再详细地深入代码,然后模拟实际情况建立如下类:

1.定义了一个加载配置文件的类Test1,使用spring注解@Service来实例化这个类。

关于java的类实例化的先后顺序_第1张图片

2.定义了一个final的工具类Test2,然后在这个类里面添加静态变量类型为Test1的test1。使用spring注解@Service来实例化这个类。

关于java的类实例化的先后顺序_第2张图片

3.定义一个需要获取Test2里面的静态方法类Test3,Test3里面有静态变量需要通过Test2的静态方法赋值。使用spring注解@Service来实例化这个类。

关于java的类实例化的先后顺序_第3张图片

好了,编译运行之后问题重现如下错误nullpointerexception:

关于java的类实例化的先后顺序_第4张图片

那么要如何解决这个问题呢?这里首先要解决思路一定要清晰,从问题报错的地方入手,明显是静态变量没有赋值,那么为什么没有赋值呢?明显的跟类加载的首先顺序有关,也就是说类的静态变量会优先执行初始化赋值,但这个时候test2尚未实例化。那么如何解决呢?这里我提供一种解决办法,就是通过init方法给静态变量赋值,如下:

关于java的类实例化的先后顺序_第5张图片

先猜猜运行结果会怎样,下面将上图:

关于java的类实例化的先后顺序_第6张图片

从结果来看解决了空指针的问题,让我们来总结一下:

1.类的静态变量,静态代码块和静态方法等会优先初始化。注意静态代码块是会有类的构造方法之前执行。

2.如果要把一个bean实例化并赋值给一个静态变量,需要使用init方法初始化并赋值。

3.一个类里面的静态变量或者静态代码块的执行先后顺序是根据在类里面定义的顺序,跟有没有final等没有关系。




你可能感兴趣的:(Java原理源码)