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

(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. vue.js中父组件触发子组件中的方法

    知识点:vue.js中,父组件的method中,触发子组件中的方法,获得子组件中的定义的属性 (1)子组件 : child_crud.js var html_child_crud= "< ...

  2. python 前置程序窗口,还原最小化的窗口

    python 前置程序窗口,还原最小化的窗口 在网上找了比较久,大多是: win32gui.FindWindow(class_name, window_name) win32gui.SetForegr ...

  3. rac 数组之遍历

    rac的数组遍历其实很简单.但是有个点需要注意. 以下先举个例子说明遍历的用法 NSArray *temArr = @["]; [temArr.rac_sequence.signal sub ...

  4. 【CF1218E】Product Tuples

    题目大意:给定一个长度为 \(N\) 的序列,求从序列中选出 \(K\) 个数的集合乘积之和是多少. 题解: 由于是选出 \(K\) 个数字组成的集合,可知对于要计算的 \(K\) 元组来说是没有标号 ...

  5. [唐胡璐]QTP技巧 - QTP菜单项消失

    有时候QTP的菜单栏的下拉菜单为空。 解决方法:在菜单栏点击右键,选择“Customize”,在Customize窗口的ToolBarTab页,点击“Restore All”后即可。

  6. Java8-Stream-No.08

    import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream; public c ...

  7. vim 插件安装

    一.pathogen简介 通常情况下安装vim插件,通常是将所有的插件和相关的doc文件都安装在中一文件夹中,如将插件全部安装在/usr/share/vim/vim73/plugin/目录下,将帮助文 ...

  8. [Luogu] 无线网络发射器选址

    https://www.luogu.org/problemnew/show/P2038 二维前缀和 #include <iostream> #include <cstdio> ...

  9. luogu4930

    P4930 「FJ2014集训」采药人的路径 题目描述 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳 ...

  10. MySQL之pymysql

    pymysql的安装 pip install PyMySQL 连接数据库   import pymysql db = pymysql.connect("数据库ip","用 ...