问题描述

最近在写一些单元测试用例,为了避免连接外界服务,所有选择mock了数据库Dao层,计划将数据库所需要的数据存在List中,在类加载的时候初始化List并且填充数据。代码如下:

 public class UserDaoMock extends UserDao {
@Override
public List<UserInfo> selectUserInfo() {
return getUserInfo();
} static {
initUserInfo();
} public static UserInfo getUserInfo() {
return userInfos;
} private static List<UserInfo> userInfos = new ArrayList<UserInfo>();
private static void initUserInfo() {
UserInfo userInfo1 = new UserInfo();
userInfo1.setId(1L);
userInfo1.setPin("user1");
userInfo1.setUserId(1L);
userInfo1.setDataBillingType(1);
userInfo1.setErp("operator1");
userInfo1.setCreatedTime("2019-01-01");
userInfo1.setModifiedTime("2019-05-01");
userInfo1.setYn(1);
userInfos.add(userInfo1); UserInfo userInfo2 = new UserInfo();
userInfo2.setId(2L);
userInfo2.setPin("user2");
userInfo2.setUserId(2L);
userInfo2.setDataBillingType(1);
userInfo2.setErp("operator2");
userInfo2.setCreatedTime("2019-01-01");
userInfo2.setModifiedTime("2019-05-01");
userInfo2.setYn(1);
userInfos.add(userInfo2); UserInfo userInfo3 = new UserInfo();
userInfo3.setId(3L);
userInfo3.setPin("user3");
userInfo3.setUserId(3L);
userInfo3.setDataBillingType(1);
userInfo3.setErp("operator1");
userInfo3.setCreatedTime("2019-01-01");
userInfo3.setModifiedTime("2019-05-01");
userInfo3.setYn(1);
userInfos.add(userInfo3);
}
}

结果在new对象的时候:

 UserDao userDao = new UserDaoMock();

一直报错:

java.lang.ExceptionInInitializerError
at com.jd.ads.afa_index.indexes.task.TestUserServiceTask.setUp(TestUserServiceTask.java:37)
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.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:119)

起初以为是init方法出错了,尝试了多种方式,才发下原来是类加载时,当执行到static{}语句块时开始调用userInfos,但userInfos这个list由于是在后面而还未定义和初始化,所以导致了错误。还是因为基础知识不扎实啊!!!

问题解决

将static对象提到最前面,即解决了此问题,简直愚昧的我啊:

 public class UserDaoMock extends UserDao {
private static List<UserInfo> userInfos = new ArrayList<UserInfo>(); @Override
public List<UserInfo> selectUserInfo() {
return getUserInfo();
} static {
initUserInfo();
} public static UserInfo getUserInfo() {
return userInfos;
} private static void initUserInfo() {
UserInfo userInfo1 = new UserInfo();
userInfo1.setId(1L);
userInfo1.setPin("user1");
userInfo1.setUserId(1L);
userInfo1.setDataBillingType(1);
userInfo1.setErp("operator1");
userInfo1.setCreatedTime("2019-01-01");
userInfo1.setModifiedTime("2019-05-01");
userInfo1.setYn(1);
userInfos.add(userInfo1); UserInfo userInfo2 = new UserInfo();
userInfo2.setId(2L);
userInfo2.setPin("user2");
userInfo2.setUserId(2L);
userInfo2.setDataBillingType(1);
userInfo2.setErp("operator2");
userInfo2.setCreatedTime("2019-01-01");
userInfo2.setModifiedTime("2019-05-01");
userInfo2.setYn(1);
userInfos.add(userInfo2); UserInfo userInfo3 = new UserInfo();
userInfo3.setId(3L);
userInfo3.setPin("user3");
userInfo3.setUserId(3L);
userInfo3.setDataBillingType(1);
userInfo3.setErp("operator1");
userInfo3.setCreatedTime("2019-01-01");
userInfo3.setModifiedTime("2019-05-01");
userInfo3.setYn(1);
userInfos.add(userInfo3);
}
}

注:

类加载时不会为实例变量赋值,对象创建时不会为静态变量赋值。我们调用静态方法时,此类就开始加载,加载的时候不会为实例变量赋值,但是会按顺序给静态变量赋值。

类加载特性 :
      *在虚拟机的生命周期中一个类只被加载一次。
      *类加载的原则:延迟加载,能少加载就少加载,因为虚拟机的空间是有限的。
      *类加载的时机:
      1)第一次创建对象要加载类.
      2)调用静态方法时要加载类,访问静态属性时会加载类。
      3)加载子类时必定会先加载父类。
      4)创建对象引用不加载类.
      5) 子类调用父类的静态方法时
          (1)当子类没有覆盖父类的静态方法时,只加载父类,不加载子类
          (2)当子类有覆盖父类的静态方法时,既加载父类,又加载子类
      6)访问静态常量,如果编译器可以计算出常量的值,则不会加载类,例如:public static final int a =123;否则会加载类,例如:public static final int a = math.PI。

转载请注明:https://www.cnblogs.com/fnlingnzb-learner/p/10615516.html

java含有静态代码块新建的时候报错java.lang.ExceptionInInitializerError的更多相关文章

  1. Java 中静态代码块初始化问题测试

    Java 中静态代码块初始化问题测试 原创 情况一:变量是 static final 修饰的"编译期常量",如 public static final String a = &qu ...

  2. (转)java中静态代码块的用法 static用法详解

    一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来 ...

  3. java中静态代码块的用法 static用法详解(转)

    (一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...

  4. 【转】java中静态代码块的用法 static用法详解

    原文网址:http://www.cnblogs.com/panjun-Donet/archive/2010/08/10/1796209.html (一)java 静态代码块 静态方法区别一般情况下,如 ...

  5. java中静态代码块的用法 static用法详解

    (一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...

  6. Java误区: 静态代码块,当把类将被载入到自己主动运行?

    JAVA静态代码块会在类被载入时自己主动运行? 非常多Java开发人员的思想,被这个思想深深的轮奸了n遍,传播这个错误思想的博客,在网上一堆,越来越多的人被轮奸. 如:http://blog.csdn ...

  7. [转载] java中静态代码块的用法 static用法详解

    一.java 静态代码块 静态方法区别 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...

  8. Java中静态代码块、构造代码块、构造函数、普通代码块

    在Java中,静态代码块.构造代码块.构造函数.普通代码块的执行顺序是一个笔试的考点,通过这篇文章希望大家能彻底了解它们之间的执行顺序. 1.静态代码块 ①.格式 在java类中(方法中不能存在静态代 ...

  9. Java的静态代码块是否会在类被加载时自动执行?

    JAVA静态代码块会在类被加载时自动执行? 一.先看Java静态方法,静态变量 http://www.cnblogs.com/winterfells/p/7906078.html 静态代码块 在类中, ...

随机推荐

  1. 简单的CSS3 Loading动画

    最终效果如图一,gif图片稍微有点卡顿,事实上代码在浏览器里执行得很流畅.这里面用到的css3技术非常简单,分别是border-radius.伪元素.css3关键帧以及animation动画. 首先整 ...

  2. odoo导入功能二开

    原来有的导入功能相信很多小伙伴对其功能不是很满意,不过没关系,我们可以二开啊,把它的功能改造成你想要的样子,接下来让我们看看怎么办吧 例如我想把员工导入功能中添加上用户同步注册功能 首先,我要找到原模 ...

  3. 1,EasyNetQ-链接到RabbitMQ

    一.链接到RabbitMQ 1,创建连接 注意不能有空格 var bus = RabbitHutch.CreateBus(“host=myServer;virtualHost=myVirtualHos ...

  4. mac那些事儿

    OS是苹果公司开发的电脑操作系统,MAC是苹果公司开发的笔记本.台式机.IOS是苹果公司开发的移动操作系统,iPhone是苹果公司研发的智能手机系列,搭载IOS操作系统. 一.mac系统快捷键 回到桌 ...

  5. 使用Plant Simulation连接SQL Server

    1. 在管理类库中添加ODBC. 2. 在控制面板->管理工具中设置ODBC,添加SQL Server服务. 3. 在plant simulation中将信息流中的ODBC添加到Frame中. ...

  6. BZOJ2915 : [Poi1997] gen

    设f[i][j]表示串ij可以由哪些字母成长过来,用二进制压位表示. 设g[i][j]表示给定串中[i,j]这个区间一开始可以由哪些字母成长多来,用二进制压位表示. 设h[i]表示给定串前i位最少需要 ...

  7. Xtreme9.0 - Car Spark 动态规划

    Car Spark 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/car-spark Descr ...

  8. 应用通信-方案一:RestTemplate

    @RestController public class ClientController { @Autowired private LoadBalancerClient loadBalancerCl ...

  9. MDK5 and STM32Cube

    D:\Workspace\........\RTE\Device>STM32CubeMX.exe -s project.script -tpl_path C:\Keil5\ARM\Pack\Ke ...

  10. vbs学习笔记1——判断文件和文件夹是否存在

    首先分享一个“VBS脚本常用经典代码收集”,这里面关于vbs很丰富的内容. 所有vbs脚本都需要保存为.vbs形式才可以运行 FileSystemObject Object的所有方法参考:http:/ ...