问题描述

最近在写一些单元测试用例,为了避免连接外界服务,所有选择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. 初识PHP(一)

    做为一名合格的前端开发攻城狮,了解一门服务端语言是必须的,所以我选了php.都说学的第一门语言对第二门语言会产生较大的影响,确实,每当我看到一个php知识点时,就同时会想到这个知识点在Javascri ...

  2. JDK1.8快速入门

    JDK8提供了非常多的便捷用法和语法糖,其编码效率几乎接近于C#开发,maven则是java目前为止最赞的jar包管理和build工具,这两部分内容都不算多,就合并到一起了. 愿编写java代码的过程 ...

  3. Typecho-Material主题不支持Kotlin代码高亮的解决方案

    Typecho-Material主题不支持Kotlin代码高亮的解决方案 Overview 最近通过Typecho搭建了一个Blog,采用了 Material主题,其他的都挺好,也挺喜欢这个主题,但是 ...

  4. [CC-FNCS]Chef and Churu

    [CC-FNCS]Chef and Churu 题目大意: 一个长度为\(n(n\le10^5)\)的数列\(A_{1\sim n}\),另有\(n\)个函数,第\(i\)个函数会返回数组中标号在\( ...

  5. QtTest模块出现控制台的原因与方案

    转到Qt安装目录下的mkspces/features目录下, 1.用记事本打开qtestlib.prf文件,注释掉CONFIG += console #CONFIG += console 2.用记事本 ...

  6. nuxus 3在Maven项目的配置和POM文件的配置

    在nuxus 3中的Maven默认会创建三个仓库,这三个仓库的关系如下: public是release和snapshot的全集,release默认为关闭状态,所以在配置nexus 3时需要将其开启. ...

  7. VMware安装MikroTik RouterOS chr

    简单步骤: 1.官网下载ova镜像 2.导入到vmware即可.

  8. C#快速找出磁盘内的所有文件

    本文只针对NTFS格式化的磁盘文件快速检索,速度不是非常快,是让你震惊. 一般用文件遍历的方法检索一个50G的文件夹需要几十分钟甚至一个小时的时间,而用本方法只需几秒. using System; u ...

  9. STM32F4: Generating parallel signals with the FSMC

    STM32F4: Generating parallel signals with the FSMC The goal: The memory controller can be used to ge ...

  10. C# 对WinForm应用程序的App.config的使用及加密

    原文地址:http://blog.163.com/zhou_zzq/blog/static/1019622120137621739874/   我们在写C#应用程序时,在工程文件中放置一个app.co ...