《Java编程思想》学习01:普通类的初始化加载顺序分析

《Java编程思想》学习01:普通类的初始化加载顺序分析

本文根据控制变量法,分析普通类(没有extends,implement)初始化的加载顺序;

参考《Java编程思想》第五章

源码

StaticClass1类

package com.tyj.study.thinkinjava;

/* *
 *@Description:
 *@Author:TYJ
 *@Date: create in  2019/7/9 17:22
 */

public class StaticClass1 {

    {
        System.out.println("我是StaticClass1的普通代码块");
    }

    static{
        System.out.println("我是StaticClass1的静态代码块");

    }
    static String staticData  = staticMethod();
    private static String staticMethod(){
        System.out.println("我是StaticClass1的静态方法");
        return "我是StaticClass1的静态方法的返回值";
    }

    public StaticClass1() {
        System.out.println("我是StaticClass1的无参构造函数");
    }

    public static void main(String[] args) {
        /*
        日志输出:
            我是StaticClass1的静态代码块
            我是StaticClass1的静态方法
        */
    }
}

StaticClass2类

package com.tyj.study.thinkinjava;

/* *
 *@Description:
 *@Author:TYJ
 *@Date: create in  2019/7/9 17:22
 */

public class StaticClass2 {

    {
        System.out.println("我是StaticClass2的普通代码块");
    }

    static String staticData  = staticMethod();
    static{
        System.out.println("我是StaticClass2的静态代码块");

    }
    private static String staticMethod(){
        System.out.println("我是StaticClass2的静态方法");
        return "我是StaticClass2的静态方法的返回值";
    }

    public StaticClass2() {
        System.out.println("我是StaticClass2的无参构造函数");
    }

    public static void main(String[] args) {
        /*
        日志输出:
            我是StaticClass2的静态方法
            我是StaticClass2的静态代码块
        */
    }
}

StaticClass3类

package com.tyj.study.thinkinjava;

/* *
 *@Description:
 *@Author:TYJ
 *@Date: create in  2019/7/9 17:22
 */

public class StaticClass3 {

    static String staticData = staticMethod();

    {
        System.out.println("我是StaticClass3的普通代码块");
    }

    static{
        System.out.println("我是StaticClass3的静态代码块");

    }

    public static String staticMethod(){
        System.out.println("我是StaticClass3的静态方法");
        return "我是StaticClass3的静态方法的返回值";
    }

    public StaticClass3() {
        System.out.println("我是StaticClass3的无参构造函数");
    }

    public static void main(String[] args) {
        StaticClass2  staticClass = new StaticClass2();

        /*
        日志输出:
            我是StaticClass3的静态方法
            我是StaticClass3的静态代码块
            我是StaticClass2的静态方法
            我是StaticClass2的静态代码块
            我是StaticClass2的普通代码块
            我是StaticClass2的无参构造函数
        */
    }
}

StaticClass4类

package com.tyj.study.thinkinjava;

/* *
 *@Description:
 *@Author:TYJ
 *@Date: create in  2019/7/9 17:22
 */

public class StaticClass4 {

    {
        System.out.println("我是StaticClass4的普通代码块");
    }

    static{
        System.out.println("我是StaticClass4的静态代码块");

    }
    static String staticData = staticMethod();

    private static String staticMethod(){
        System.out.println("我是StaticClass4的静态方法");
        return "我是StaticClass4的静态方法的返回值";
    }

    public StaticClass4() {
        System.out.println("我是StaticClass4的无参构造函数");
    }

    public static void main(String[] args) {
        StaticClass3.staticMethod();

        /*
        日志输出:
            我是StaticClass4的静态代码块
            我是StaticClass4的静态方法
            我是StaticClass3的静态方法
            我是StaticClass3的静态代码块
            我是StaticClass3的静态方法
        */
    }
}

StaticClass5类

package com.tyj.study.thinkinjava;

/* *
 *@Description:
 *@Author:TYJ
 *@Date: create in  2019/7/9 17:22
 */

public class StaticClass5 {

    {
        System.out.println("我是StaticClass5的普通代码块");
    }

    static{
        System.out.println("我是StaticClass5的静态代码块");

    }
    static String staticData = staticMethod();

    private static String staticMethod(){
        System.out.println("我是StaticClass5的静态方法");
        return "我是StaticClass5的静态方法的返回值";
    }

    public StaticClass5() {
        System.out.println("我是StaticClass5的无参构造函数");
    }

    public static void main(String[] args) {
        StaticClass5 a = new StaticClass5();
        StaticClass5 b = new StaticClass5();

        /*
        日志输出:
            我是StaticClass5的静态代码块
            我是StaticClass5的静态方法
            我是StaticClass5的普通代码块
            我是StaticClass5的无参构造函数
            我是StaticClass5的普通代码块
            我是StaticClass5的无参构造函数
        */
    }
}

分析

  1-分析StaticClass1,可以发现只要调用类的静态方法(即main方法),类的静态方法和静态变量都会被加载,即执行一次;

  2-分析StaticClass1和StaticClass2,可发现类的静态方法和静态变量调用顺序只和其在类中的代码顺序有关,即谁在前,先执行谁;

  3-分析StaticClass3,当调用StaticClass3的main方法时,会先初始化StaticClass3的静态方法和静态代码块,在执行main方法内的代码;

  4-继续分析StaticClass3;执行main方法内的StaticClass2  staticClass = new StaticClass2()时,会依次初始化StaticClass2的静态方法和静态变量,普通代码块,构造函数;

  5-分析StaticClass4;当调用StaticClass4的main方法时,会先初始化StaticClass4的静态方法和静态代码块;然后执行StaticClass3.staticMethod(),这里直接调用StaticClass3的静态方法(没有实例一个StaticClass3对象),StaticClass3的静态变量和静态代码块也被初始化了;

  6-分析StaticClass5;发现连续创建两个StaticClass5类时,普通代码块和构造函数会被加载两次,但静态代码块和静态变量,只会加载一次

总结

  1-当创建一个对象,或者执行类的静态方法时,类的静态变量和静态代码块,都会被先加载一次;

  2-多次创建对象或执行类的静态方法时,类的静态变量和静态代码块只会在第一次被加载,后面不会被重复加载;

  3-当创建一个对象时,会依次加载:

    • 类的静态代码块和静态变量(两者按代码顺序加载,且两者只会被加载一次,不会重复加载);
    • 类的普通代码块(每创建一个对象,普通代码块就会被加载一次);
    • 类的构造函数(每创建一个对象,构造函数就会被加载一次);

原文地址:https://www.cnblogs.com/wobuchifanqie/p/11159370.html

时间: 2024-10-31 05:19:46

《Java编程思想》学习01:普通类的初始化加载顺序分析的相关文章

Java编程思想学习(五) 复用类

1.继承与组合 复用类的方法有两种:继承与组合.继承就不多说了,组合就是直接在类中new一个对象. 数组也是对象,使用数组也是组合的一种. 2.初始化基类 当创建一个导出类的对象时,该对象包含一个基类的子对象.这个子对象跟直接new一个基类的对象完全相同,唯一的区别是:一个在外部,一个被包装在导出类对象内部. 在导出类构造器中,通过调用基类构造器来执行初始化.[在Java中,所有导出类的所有构造器内部都必须调用父类的某一个构造器或所有导出类的所有构造器内部都必须调用一个其他构造器(既可以是本类构

【Java编程思想--学习笔记(一)】访问控制-包

Java编程思想–学习笔记(一) 访问控制(或隐藏具体实现)与"最初的实现并不恰当"有关. 1.包:库单元 我们之所以要导入包,就是要提供一个管理名字的空间机制. 每个java文件只能有一个public类.其他私有类为主public·类提供支持. 1.1 代码组织 与编译型语言不同,java可运行程序是一组可以打包并压缩成java文档文件(JAR,使用Java的jar文档生成器)的.class文件. 使用package和import关键字,使得不会出现名称冲突问题. 注意:java包的

Java编程思想学习第一天

今天开始正式学习Java编程思想,把遇到的一些比较经典的语句记录下来,作为自己学习的一份成果! 一. 面向对象的基本特性: 第一:万物皆为对象        第二:程序是对象的集合,他们通过发送消息来告知彼此所要做的   第三:每个对象都有自己的由其他对象所构成的存储   第四:每个对象都拥有其类型   第五:某一特定类型的所有对象都可以接收同样的消息   对象具有状态.行为和标识 二. 每个对象都提供服务      1. 将对象想象为一个服务提供者,程序本身将向用户提供服务 2. 将对象想象为

Yaf零基础学习总结5-Yaf类的自动加载

Yaf零基础学习总结5-Yaf类的自动加载 框架的一个重要功能就是类的自动加载了,在第一个demo的时候我们就约定自己的项目的目录结构,框架就基于这个目录结构来自动加载需要的类文件. Yaf在自启动的时候, 会通过SPL注册一个自己的Autoloader, 出于性能的考虑, 对于框架相关的MVC类, Yaf Autoloader只以目录映射的方式尝试一次. 具体的目录映射规则如下: 对于控制器 Controller 默认模块下为{项目路径}/controllers/, 否则为{项目路径}/mod

JAVA编程思想学习笔记——第一章 对象导论

搞了一年多java,野路子出身,发现java基础这块还是相当的薄弱!故决定学习<Java编程思想>这本书.在此把学习的知识点记录下! 面向对象的五大特性 1.万物皆为对象 2.程序是对象的集合,它们通过发送消息来告诉彼此所要做的 3.每个对象都由自己的由其它对象所构成的存储 4.每个对象都拥有其类型 5.某一特定类型的所有对象都可以接收同样的信息  单根继承结构 所有的类都继承自单一的基类,Object.在单根集成结构中的所有对象都具有一个公用接口,所以他们归根到底都是相同的基本类型.单根集成

java编程思想学习(1)

Smalltalk 这是第一种成功的面向对象程序设计语言,也是Java 的基础语言.Smalltalk (java的基础语言)的五大基本特征: (1) 所有东西都是对象.可将对象想象成一种新型变量:它保存着数据,但可要求它对自身进行操作.理论上讲,可从要解决的问题身上提出所有概念性的组件,然后在程序中将其表达为一个对象. (2) 程序是一大堆对象的组合:通过消息传递,各对象知道自己该做些什么.为了向对象发出请求,需向那个对象"发送一条消息".更具体地讲,可将消息想象为一个调用请求,它调

[Java编程思想-学习笔记]第3章 操作符

3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("Hello, world"); 我们都会感觉太冗长了,能不能简单一些呢?静态导入可以省略掉System,就像这样 import static java.lang.System.*; public class Hello { public static void main(String[] args) {

【java编程思想--学习笔记(四)】对象导论

写这篇博客的前言: 长话短说,我希望通过阅读<java编程思想>来使我的代码 简洁可用 . 目的的层次不同,首先具体的目标是,了解Java的特性和巩固Java的基础. 更抽象的目的如下: 1.期待以巩固基础的方式,使代码优美,简洁,高效. 2.使自己写的模块能够开放适度,好用. 3.形成一种对代码是否优美的审美观. 于是<Java编程思想>第一章 对象导论 由此开始. 1.1 抽象过程 java 相对于命令式语言的优势在于只针对于待解问题建模.后者所做的主要抽象要求所做问题基于计算

java 类属性的加载顺序(带有继承关系的)

工作有三年之久了,突然感觉带有继承关系.父子俩既有静态变量又有成员变量的情况,变量的加载顺序很容易混淆,今晚写了个例子,总算是把关系搞清楚了 例子中,父类既有普遍的成员变量,也有static变量,也有static代码块,在父类的构造器前后都有static变量及普通变量,让我们看看初始化子类的时候会发生什么吧 先提供完整代码: LoadSequence.java public class LoadSequence { public static void main(String[] args) {