1、问题描述
java.lang.ExceptionInInitializerError
at com.crazymakercircle.zk.NameService.SnowflakeIdWorkerTest.test(SnowflakeIdWorkerTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NullPointerException
at com.crazymakercircle.zk.NameService.BaseClass.<init>(BaseClass.java:21)
at com.crazymakercircle.zk.NameService.BaseClass.<clinit>(BaseClass.java:16)
... 23 more
2、问题代码
首先写一个BaseClass
,定义一个静态方法,实现单例的功能。源码如下:
package com.crazymakercircle.zk.NameService;
/**
* @author Chen
* @version 1.0
* @date 2020/4/16 13:21
* @description:
*/
public class BaseClass {
//客户端
private Object client = null;
public static BaseClass instance = new BaseClass();
private BaseClass() {
BaseClass.instance.client = new Object();
BaseClass.instance.init();
}
private void init() {
System.out.println("init");
}
public void hello() {
System.out.println("-----------chen---------------> hello");
}
}
测试类功能就是获取BaseClass
实例对象并调用hello()
方法。源码如下:
import org.junit.Test;
/**
* @author Chen
* @version 1.0
* @date 2020/4/16 13:19
* @description:
*/
public class SnowflakeIdWorkerTest {
@Test
public void test(){
BaseClass.instance.hello();
}
}
2、问题分析
private BaseClass() {
BaseClass.instance.client = new Object();
BaseClass.instance.init();
}
这是由于在静态变量client
的初始化还未执行之前就使用该静态变量。有种相互引用的感觉。
3、问题解决
既然知道是在静态变量client
的初始化还未执行之前就使用该静态变量而出现的问题。那么我们直接使用成员变量即可。修改之后源码如下:
package com.crazymakercircle.zk.NameService;
import com.crazymakercircle.zk.ZKclient;
/**
* @author Chen
* @version 1.0
* @date 2020/4/16 13:21
* @description:
*/
public class BaseClass {
//客户端
private Object client = null;
public static BaseClass instance = new BaseClass();
private BaseClass() {
this.client = new Object();
this.init();
}
private void init() {
System.out.println("init");
}
public void hello() {
System.out.println("-----------chen---------------> hello");
}
}
再次运行上面的测试类,控制台输出如下:
init
-----------chen---------------> hello
Process finished with exit code 0
完美输出结果。问题解决。
4、总结
书上的代码直接运行绝大部分是对的,但是总有一些软件的更新使得作者无能为力。之前的API是对的,但是之后就废弃了或修改了是常有的事。所以我们需要跟踪源代码。这只是一个小小的问题,如果没有前辈的无私奉献,很难想象我们自己一天能学到多少内容。感谢各位前辈的辛勤付出,让我们少走了很多的弯路!
点个赞再走呗!欢迎留言哦!