参考文章:【https://www.cnblogs.com/maohuidong/p/7843807.html】

前言:

  在看单例模式的时候,在网上找帖子看见其中有一种(IoDH) 实现单例的方式,其中用到了静态内部类,文章中有写到当jvm加载外部类的时候,并没有加载静态内部内这和之前自己想的不一样,特意在网上找了一些帖子总结一下。

一、学习前千的疑问:

  稍微了解Java虚拟机内的加载过程的步骤,都很清楚,一个类的静态资源、一些常量都是在类加载的时候就被加载金内存中分配空间了,所以我一开始理所当然的以为静态内部类中的静态变量同样属于静态资源,也应该在在内加载的时候被加载,然而实际情况却不是这样的,带着这个问题我上网找了几篇博客查找原因。

二、探究的过程:

  在这里我们直接上一段代码,在这里我们分别进行三次测试来:

public class StaticClass {

    public static long OUTER_DATE = System.currentTimeMillis();

    static {
System.out.println("外部类静态块加载时间:" + System.currentTimeMillis());
} public StaticClass() {
System.out.println("外部类构造函数时间:" + System.currentTimeMillis());
} static class InnerStaticClass {
public static long INNER_STATIC_DATE = System.currentTimeMillis();
static{
System.out.println("静态内部类静态块加载时间:" + System.currentTimeMillis());
}
} class InnerClass {
public long INNER_DATE = 0;
public InnerClass() {
INNER_DATE = System.currentTimeMillis();
}
}
}

  1、当外部内静态变量被调用

public static void main(String[] args) {
StaticClass outer = new StaticClass();
System.out.println("外部类静态变量加载时间:" + outer.OUTER_DATE);
}

  打印结果:

 外部类静态块加载时间:1556088212487
 外部类构造函数时间:1556088212487
 外部类静态变量加载时间:1556088212487

  从控制台打印的结果我们可以看到:

    外部静态变量调用时,外部内进行了加载(注:静态代码块在类被加载时执行)并且执行了初始化操作(注:构造方法被调用),而静态内部类并没有被加载(注:静态内部类中的静态代码块没有执行),且类的加载顺序必定会在初始化的前面,所有看到先执行了静态代码块中的代码,其次执行了构造方法中的代码,完成上面两部后最后才打印出了静态变量

  2、非静态内部类变量调用时:

 public static void main(String[] args) {
StaticClass outer = new StaticClass();
System.out.println("非静态内部类加载时间"+outer.new InnerClass().INNER_DATE);
}

  打印结果:

外部类静态块加载时间:1556088682706
外部类构造函数时间:1556088682706
非静态内部类加载时间1556088682707

  从控制台打印的结果我们可以看到:

    非静态内部类变量被调用时的执行结果和外部静态变量被调用的结果一样,并且静态内部类也没有被加载,出现这种情况也在预料之中,因为非静态内部类的初始化不许依赖于外部类,如果想实例化一个非静态内部类,则必须先实例化外部类,所以我们就看到了上面的结果

  3、静态内部类中的变量被调用时:

public static void main(String[] args) {
System.out.println("静态内部类加载时间:"+InnerStaticClass.INNER_STATIC_DATE);
}

  测试结果:

 外部类静态块加载时间:1556089480349
 静态内部类静态块加载时间:1556089480352
 静态内部类加载时间:1556089480352

  从控制台打印的结果我们可以看到:

    静态内部类的变量被调用时,我们可以看出外部类进行了加载(注:外部类中的静态代码块中的代码执行了),但是并没有被初始化(注:外部类的构造方法并没有执行),且静态内部类也完成了加载

三、得出结论:

  有上面我们进行的测试可以得出结论,静态内部类和非静态内部类一样,都不会因为外部内的加载而加载,同时静态内部类的加载不需要依附外部类,在使用时才加载,不过在加载静态内部类的过程中也会加载外部类

Java 静态内部类的加载时机的更多相关文章

  1. JVM中java类的加载时机(转载:http://blog.csdn.net/chenleixing/article/details/47099725)

    Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制.类从被加载到虚拟机内存中开始,到卸载出内 ...

  2. Java类的加载时机

    但是对于初始化阶段,虚拟机规范则是严格规定了有且只有5种情况必须立即对类进行“初始化”(而加载.验证.准备自然需要在此之前开始):1)遇到new.getstatic.putstatic或invokes ...

  3. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  4. Java类的加载

    1.类的加载步骤 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化三步来实现对这个类的初始化 加载:将class文件读入内存,并为之创建一个Class对象,任何类被使用 ...

  5. Java中类的加载、连接和初始化

    Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...

  6. Java类的加载、链接和初始化

    一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...

  7. java 类的加载,链接,初始化

    本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...

  8. JAVA类的加载、连接与初始化

    JAVA类的加载.连接与初始化 类的声明周期总共分为5个步骤1.加载2.连接3.初始化4.使用5.卸载 当java程序需要某个类的时候,java虚拟机会确保这个类已经被加载.连接和初始化,而连接这个类 ...

  9. Java类的加载与生命周期

    一.概要: 类的生命周期从类的 加载.连接.初始化 开始,到类的 卸载结束: 二.几个阶段: 加载:查找并加载类的二进制数据.(把类的.class文件的二进制数据读入内存,存放在运行时数据区的方法区: ...

随机推荐

  1. java~接口的共享实体使用Map后更灵活

    微服务时代的实体设计 在一个微服务时代,一个实体参数或者返回值,它可能是多服务之前共享的,而这个重复的实体你需要拷贝多份,这是违背DRP原则的,所以我们需要找一种更友好的方式来代替它,它就是Map,我 ...

  2. 微信小程序开发06-一个业务页面的完成

    前言 接上文:微信小程序开发05-日历组件的实现 github地址:https://github.com/yexiaochai/wxdemo 这里来说一说我们的理念,我们也学习小程序开发有一周多了,从 ...

  3. svn 卡死住,关闭后,用CleanUp报错解决

    一.问题描述: 经常用SVN的人都知道,有时候更新文件更新着更新一般,突然卡顿住,死在那边动都不动出现提示:svn cleanup failed–previous operation has not ...

  4. 关于jQuery中的选择器

    1:选择器的作用 获取网页的上面的标签元素等等,然后对他进行一些列的操作(添加样式,添加行为...) 2:选择器有哪些 基本选择器,层次选择器,过滤选择器,表单选择器 一:基本选择器 基本选择器是jq ...

  5. vue 使用定时器setInterval

    来自:https://www.jianshu.com/p/180957762852 侵删 beforeMount() { //车辆进出设置定时器,每3秒刷新一次 var self = this; cl ...

  6. vue中使用百度地图,悬浮窗搜索功能

    https://www.cnblogs.com/shuaifing/p/8185311.html 侵删 <template> <div id="all"> ...

  7. 图像的膨胀与腐蚀——OpenCV与C++的具体实现

    目录 1. 膨胀与腐蚀的原理 2. 膨胀的具体实现 1) OpenCV实现 2) C/C++实现 3) 验证与结果 3. 腐蚀的具体实现 1. 膨胀与腐蚀的原理 膨胀与腐蚀是数学形态学在图像处理中最基 ...

  8. VS fopen sprinft ... unsafe 问题

    我的用的是VS2017 VS项目->右键属性(最下面)->C/C++->预处理器->预处理器定义->编辑->加上_CRT_SECURE_NO_WARNINGS  - ...

  9. SQLServer之创建不可重复读

    创建不可重复读注意事项 语法:set transaction isolation level repeatable read. 指定语句不能读取已由其他事务修改但尚未提交的行,并且指定,其他任何事务都 ...

  10. JAVA EE获取浏览器和操作系统信息

    一.原理说明:  1. 浏览器访问服务端时,Http请求头上会带上客户端一些信息,可通过"user-agent"获取. //java获取方法如下,其他语言也有自己获取方法 Stri ...