问题描述

最近在写一些单元测试用例,为了避免连接外界服务,所有选择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. rabbitmq学习(五) —— 路由

    绑定(Bindings) 在上一个教程中,我们已经使用过绑定.你可能会记得如下代码: channel.queueBind(queueName, EXCHANGE_NAME, "") ...

  2. Android-LayoutAnimation

    Android-LayoutAnimation 学习自 <Android开发艺术探索> LayoutAnimation漫谈 LayoutAnimation 也是View动画的一种,作用是为 ...

  3. Fisher–Yates shuffle 洗牌算法(zz)

    1,缘起 最近工作上遇到一个问题,即将一组数据,比如[A,B,C,D,E]其中的两个B,E按随机排列,其他的仍在原来的位置: 原始数组:[A,B,C,D,E] 随机字母:[B,D] 可能结果:[A,B ...

  4. 李善友《认知升级之第一性原理》--507张PPT全解!_搜狐科技_搜狐网

      http://www.sohu.com/a/151470602_733114

  5. oracle直接读写ms sqlserver数据库(二)配置透明网关

    环境说明: 数据库版本:11gR2 透明网关版本:11g 操作系统Windows Server2008_64位 ORACLE_HOME目录:D:\app\Administrator\product\1 ...

  6. LDO current regulator for power LED

    LDO current regulator for power LED Challenge You've got a power LED? Great! Build a flash light! Wh ...

  7. ARM架构--CPU的微架构

    网上确实有说ARM架构的,但是此架构泛指用ARM指令系统的CPU,而不是CPU的微架构.,硬件电路上,要用ARM指令集系统,必然硬件设计电路上要要遵循,ARM指令的特点和寻址方式,所以说高通和苹果的C ...

  8. 在树莓派2上安装 Windows 10

    微软在2015年4月29日发布了树莓派玩家期待已久的 Windows 10 物联网核心预览版(Windows 10 IoT Core Insider Preview Image for Raspber ...

  9. error CS0234: 命名空间“XXX”中不存在类型或命名空间名称“UserInfoVm”(是否缺少程序集引用?)

    □ 背景 UserInfoVm是在MVC的Models文件夹中的一个view model,这个view model是某部分视图的的页面Model.当加载这个部分视图的时候报了错. □ 思考 UserI ...

  10. Net Framework 2.0 MSI returned error code 1603解决方法

    出现这种情况的原因,主要是用ghost做的系统,有很多系统中把ie给绑架了.下面的截图就是ghost做的系统中注册表的显示,通过上面的方法就可以解决这种Microsoft .NET Framework ...