每个类的编译代码都存在于它自己的独立文件中,该文件在需要使用该程序代码时才会被加载。通常有以下三种加载情况:

(1) 访问了子类的静态变量或静态方法:仅对类的静态变量,静态块执行初始化操作,并仅初始化一次。[代码1]

初始化的顺序:父类的静态变量,静态块 --> 子类的静态变量,静态块 (静态域仅初始化一次)

(2) 通过构造器创建了子类的第一个对象[new XX()]:不仅对类的静态变量,静态块执行初始化操作, 还会对实例变量,块执行初始化操作[代码2]

初始化的顺序:父类的静态变量,静态块 --> 子类的静态变量,静态块 --> 父类的实例变量,块 --> 父类的构造器 --> 子类的实例变量,块 --> 子类的构造器 (静态域仅初始化一次)

(3) 反射: 使用[Class.forName()]时同(1),使用[newInstance()]时同(2)。[代码3]

注意事项:

(A1) 子类访问父类的静态域,子类只会初始化父类的静态变量,静态块。不会初始化自己的。

(A2) 仅仅初始化一个数组对象是不会对此对象初始化的。

 

[代码1]

     public static void main(String[] args) throws Exception {
ParentClass.parentStaticMethod();
}

output:

Call: ParentClass >> parentField2
Call: ParentClass >> static block
Call: ParentClass >> parentStaticMethod

[代码2]

     public static void main(String[] args) throws Exception {
new ChildClass();
}

output:

Call: ParentClass >> parentField2
Call: ParentClass >> static block
Call: ChildClass >> childField2
Call: ChildClass >> static block
Call: ParentClass >> parentField1
Call: ParentClass >> block
Call: ParentClass >> constructor
Call: ChildClass >> childField1
Call: ChildClass >> block
Call: ChildClass >> constructor

[代码3]

     public static void main(String[] args) throws Exception {
System.out.println("--execute: forName----");
Class<?> clazz = Class.forName("ChildClass");
System.out.println("--execute: newInstance----");
clazz.newInstance();
}

output:

--execute: forName----
Call: ParentClass >> parentField2
Call: ParentClass >> static block
Call: ChildClass >> childField2
Call: ChildClass >> static block
--execute: newInstance----
Call: ParentClass >> parentField1
Call: ParentClass >> block
Call: ParentClass >> constructor
Call: ChildClass >> childField1
Call: ChildClass >> block
Call: ChildClass >> constructor

ParentClass.java

 public class ParentClass {

     String parentField1 = parentMethod1();

     static String parentField2 = parentMethod2();

     {
System.out.println("Call: ParentClass >> block");
} static {
System.out.println("Call: ParentClass >> static block");
} ParentClass() {
System.out.println("Call: ParentClass >> constructor");
} String parentMethod1() {
System.out.println("Call: ParentClass >> parentField1");
return null;
} static String parentMethod2() {
System.out.println("Call: ParentClass >> parentField2");
return null;
} static String parentStaticMethod() {
System.out.println("Call: ParentClass >> parentStaticMethod");
return null;
}
}

ChildClass.java

 public class ChildClass extends ParentClass {

     String childField1 = childMethod1();

     static String childField2 = childMethod2();

     {
System.out.println("Call: ChildClass >> block");
} static {
System.out.println("Call: ChildClass >> static block");
} ChildClass() {
System.out.println("Call: ChildClass >> constructor");
} String childMethod1() {
System.out.println("Call: ChildClass >> childField1");
return "";
} static String childMethod2() {
System.out.println("Call: ChildClass >> childField2");
return "";
} static String childStaticMethod() {
System.out.println("Call: ChildClass >> childStaticMethod");
return null;
}
}

Java类的加载及初始化的更多相关文章

  1. Java类的加载 链接 初始化

    原文地址 Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码到能够 ...

  2. Java 类的加载与初始化

    本文结构: 1.先看几道题 2.类的加载于初始化 (1)类的加载 (2)类的初始化 (a)会发生类的初始化的情况 (b)不会发生类的初始化的情况 首先看几道题. 解析可在看完讲解后再看 Demo1 p ...

  3. java类的加载以及初始化顺序

    类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...

  4. java类的加载与初始化

    https://blog.csdn.net/u013349237/article/details/71076617 1在命令行启动虚拟机jvm进行加载, 2用class.forname()方法进行动态 ...

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

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

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

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

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

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

  8. java 类的加载、连接和初始化

    JVM和类 调用Java命令运行Java程序时,该命令将会启动一条Java虚拟机进程,不管该Java程序启动了多少条线程,创建了多少个变量,它们都处于该Java虚拟机进程里,共享该JVM进程的内存区. ...

  9. java类从加载、连接到初始化过程

    类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个Class对象,存储在.class文件中,JV ...

随机推荐

  1. MNPR--造福人类的人值得被感激

    https://artineering.io/research/MNPR/ https://mnpr.artineering.io https://pdfs.semanticscholar.org/0 ...

  2. iphone bandwidth

    iPhone 8, 8 Plus, X peak throughput of ~24GBs iPhone XS, XS Max, XR peak throughput of ~34GBs 在iphon ...

  3. BZOJ 1453 (线段树+并查集)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1453 题意:一个 n*n 的矩阵,每个位置有黑/白两种颜色,有 m 次操作,每次可以翻转 ...

  4. 制作自己的livecd

    把现有ubuntu系统打包,迁移到另外一台硬件一模一样的机器上. https://zhuanlan.zhihu.com/p/51827233 https://blog.csdn.net/vah101/ ...

  5. CaoHaha's staff (HDU 6154)(2017中国大学生程序设计竞赛 - 网络选拔赛)

    Problem Description "You shall not pass!" After shouted out that,the Force Staff appered i ...

  6. ida 下载

    链接:https://pan.baidu.com/s/1Rs2UOSfroBGf_MIkJv0cGw 提取码:kjqd 官网:https://www.hex-rays.com/updida.shtml

  7. Codeforces 55D. Beautiful numbers(数位DP,离散化)

    Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...

  8. oracle面试题2

    1.题目要求 为管理岗位业务培训信息,建立3个表:S (S#,SN,SD,SA) S#,SN,SD,SA 分别代表学号.学员姓名.所属单位.学员年龄C (C#,CN ) C#,CN 分别代表课程编号. ...

  9. java TimeUnit 的使用

    主要作用 时间颗粒度转换 延时 1.时间颗粒度转换 public long toMillis(long d) //转化成毫秒 public long toSeconds(long d) //转化成秒 ...

  10. 关于AngularJS与其他前端框架混合使用的思考

    AngularJS 是一个为动态WEB应用设计的结构框架,拥有双向数据绑定,模板,MVVM,依赖注入,指令5大优点,Angular最有诱惑力的就是数据绑定功能,使用MVC模式进行开发,Angular在 ...