`

【转】Java程序员的日常 —— Java类加载中的顺序

阅读更多

来源:http://www.cnblogs.com/xing901022/p/5507086.html

 

之前说过Java中类的加载顺序,这次看完继承部分,就结合继承再来说说类的加载顺序。

继承的加载顺序

由于static块会在首次加载类的时候执行,因此下面的例子就是用static块来测试类的加载顺序。

package xing.test.thinking.chap7;
class A{
    static{
        System.out.println("A static");
    }
}
class B extends A{
    static{
        System.out.println("B static");
    }
}
class C extends B{
    private static D d = new D();
    static{
        System.out.println("C static");
    }
}
class D{
    static{
        System.out.println("D static");
    }
}
public class ExtendTest {
    public static void main(String[] args) {
        C c = new C();
    }
}

在上面的例子中,类C继承B,B继承A,而C有依赖于D。因此当创建C的时候,会自动加载C继承的B和依赖的D,然后B又会加载继承的A。只有A加载完,才能顺利的加载B;BD加载完,才能加载C。这就是类的加载顺序了。

A static
B static
D static
C static

所有的变量初始化完,才会执行构造方法

在类的加载过程中,只有内部的变量创建完,才会去执行这个类的构造方法。

package xing.test.thinking.chap7;
class A2{
    B2 b2 = new B2();
    static{
        System.out.println("A static");
    }
    public A2() {
        System.out.println("A2()");
    }
}
class B2{
    C2 c2 = new C2();
    D2 d2 = new D2();
    static{
        System.out.println("B static");
    }
    public B2() {
        System.out.println("B2()");
    }
}
class C2{
    static{
        System.out.println("C static");
    }
    public C2() {
        System.out.println("C2()");
    }
}
class D2{
    static{
        System.out.println("D static");
    }
    public D2() {
        System.out.println("D2()");
    }
}
public class VarTest {
    public static void main(String[] args) {
        A2 a2 = new A2();
    }
}

在上面的例子中,A2里面有B2变量,B2则有C2D2变量。因此类的加载还是先读取到哪个,就执行相应的静态块。
当依赖的对象都定义完,才会执行构造方法:

A static
B static
C static
C2()
D static
D2()
B2()
A2()

静态成员与普通成员类的加载区别

在类的加载过程中,静态成员类的对象,会优先加载;而普通成员类的对象则是使用的时候才回去加载。

package xing.test.thinking.chap7;
class A3{
    B3 b3 = new B3();
    static C3 c4 = new C3();
    static{
        System.out.println("A3");
    }
}
class B3{
    static{
        System.out.println("B3");
    }
}
class C3{
    static{
        System.out.println("C3");
    }
}
public class StaticTest {
    public static void main(String[] args) {
        A3 a3 = new A3();
    }
}

输出:

C3
A3
B3

总结

第一点,所有的类都会优先加载基类
第二点,静态成员的初始化优先
第三点,成员初始化后,才会执行构造方法
第四点,静态成员的初始化与静态块的执行,发生在类加载的时候。
第四点,类对象的创建以及静态块的访问,都会触发类的加载。

补充类构造方法的顺序

看代码:

package xing.test.thinking.chap8;
class A{
    public A() {
        System.out.println("A");
    }
}
class B extends A{
    public B() {
        System.out.println("B");
    }
}
class C extends B {
    private D d1 = new D("d1");
    private D d2 = new D("d2");
    public C() {
        System.out.println("C");
    }
}
class D {
    public D(String str) {
        System.out.println("D "+str);
    }
}
public class ExtendTest {
    public static void main(String[] args) {
        C c = new C();
    }
}

执行结果:

A
B
D d1
D d2
C

因此可以得出结论:

  • 首先会调用基类的构造方法
  • 其次,调用成员的构造方法
  • 最后,调用自己的构造方法
分享到:
评论

相关推荐

    黑马程序员入学Java知识——精华总结.doc

    - **健壮性**:Java有严格的类型检查和异常处理机制,能减少程序中的错误。 - **高效性**:虽然Java是解释型语言,但JVM通过即时编译(JIT)提升运行效率。 3. **JRE与JDK的区别**: JRE(Java Runtime ...

    Java面试之——代码与编程题

    【Java面试之——代码与编程题】是Java程序员在求职过程中常常遇到的面试环节,主要考察应聘者对Java语言的理解和实际操作能力。面试中,面试官可能会提出各种类型的编程题目,包括但不限于设计模式、继承机制、内部...

    JAVA面试题解惑系列——类的初始化顺序

    在Java中,类的初始化顺序是一个经常被问及的面试题目,尤其对于Java程序员和工程师来说,了解这个知识点是必须的。在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面...

    坚持写博客第一周--java基础知识回顾--jvm类加载1(csdn)————程序.pdf

    此外,还可以查看类加载器加载的类路径,了解类的来源和加载顺序。 总之,JVM的类加载机制是Java运行时的关键部分,它保证了程序的稳定性和安全性,同时也提供了灵活性,使得我们可以自定义加载逻辑,满足特定场景...

    Jave深度历险(CH_02深入类别载入器)

    例如,在企业级应用服务器中,为了支持热部署(Hot Deployment)——即在服务器不停机的情况下更新服务组件,通常会自定义类加载器。通过自定义类加载器,开发者能够精确控制类的加载时机、来源以及加载策略,实现更为...

    JAVA面试题解惑系列.doc

    总的来说,理解和掌握类的初始化顺序是Java程序员必备的基础知识,它不仅有助于编写正确的代码,也能帮助我们在面试中自信地解答相关问题。通过实践和测试,我们可以更好地理解这些概念,提高编程技能。

    java版植物大战僵尸源码

    《Java版植物大战僵尸源码解析》 在编程领域,源码是理解程序运作机制的钥匙,对于开发者来说,能够深入研究一款游戏的源码,无疑是提升...因此,对于有志于游戏开发的Java程序员来说,这是一个不可多得的学习材料。

    class_java.zip

    同时,类的静态变量和静态块、实例变量和构造函数的初始化顺序,以及单例模式的实现等,都是Java程序员必须掌握的基础知识。 除此之外,Java集合框架、多线程、网络编程、I/O流、反射、注解等高级特性,也是"源码...

    java面试题

    这种特性主要得益于 Java 字节码(Bytecode)及其运行环境——Java 虚拟机(JVM)。 - **编译过程**:Java 源代码首先被编译成与平台无关的字节码文件(.class 文件),而不是直接转换为机器码。 - **JVM的作用**:...

    推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 02.理解结构化程序设计_理解面向对象(共25页).ppt

    包括数据类型、运算符、流程控制、数组、面向对象、异常处理、图形界面编程(AWT和Swing)、JDBC数据库访问、注解、输入输出、多线程、网络编程、类加载与反射等,全面覆盖了Java程序员所需的基础知识。 总结来说,...

    俄罗斯方块Java篇

    在编程领域,Java是一种广泛应用的编程语言,以其“一次编写,到处运行”的特性深受程序员喜爱。本篇文章将深入探讨如何使用Java语言来实现经典的游戏——俄罗斯方块。俄罗斯方块是一款极具挑战性的益智游戏,自1984...

    jdk11(开源免费版).rar

    Java Development Kit(JDK)是Java程序员进行开发、编译和运行Java程序所需的核心工具集。JDK11是Oracle公司发布的Java平台标准版(Java SE)的一个重要版本,它在2018年9月发布,带来了许多新特性和改进。这个开源...

    程序员角度深入理解计算机系统

    - **链接与加载**:介绍链接器如何将多个对象文件组合成一个可执行文件,以及加载器如何将程序加载到内存中运行。 ### 知识点四:编译系统的工作原理 **标题**:“1.3 了解编译系统如何工作至关重要” **描述**:...

    java设计模式(1)

    ### Java设计模式(1)——理解与应用 #### 一、设计模式概述 设计模式是在软件工程领域中,为了应对特定问题或情境而形成的最佳实践集合。这些模式可以帮助开发者更高效地解决常见问题,提高代码的可重用性和可...

    java面试宝典

    **深入探讨**:可以进一步讨论JVM的内部结构,如类加载器、垃圾回收机制等。 #### 四、就业与薪资 - **初级程序员**:薪资范围通常在2000-4500元之间。 - **中级程序员**:薪资范围大约在4000-7000元。 - **高级...

    JVM面试复习.pdf

    #### JMM——Java内存模型 - **定义**:定义了Java虚拟机在计算机内存中的工作方式,是JVM的一部分。 - **抽象关系**:线程和主内存之间的关系,共享变量存储在主内存中,每个线程拥有自己的本地内存,本地内存存储...

    2021-2022计算机二级等级考试试题及答案No.11948.docx

    **题目**: 简述加载页面时,`page`类各事件的发生顺序。 **答案要点**: - 第01步: 内容页的 `Page_PreInit` —— 在这个阶段,ASP.NET 会初始化页面的一些基本属性,比如主题、皮肤等。 - 第02步: 母版页的 `Page_...

    ProgrammersGuide

    标题:程序员指南——深入理解Byteman工具 ### 引言与概述 Byteman是Red Hat提供的一个强大且灵活的工具,专为Java开发者设计,用于动态地修改正在运行的Java应用程序的行为。通过Byteman,开发人员可以在不重新...

    Kettle数据库同步源码

    此外,Kettle提供了图形化的设计界面—— Spoon,使得非程序员也能方便地创建和调试转换。但深入理解源码,对于解决复杂问题和优化性能具有重要意义。例如,通过对`org.pentaho.di.core.database.Database`类的理解...

Global site tag (gtag.js) - Google Analytics