什么时候会加载类

使用到类中的内容时加载,三种情况:

  • 创建对象:new StaticDemo();
  • 使用类中的静态成员:StaticCode.num = 9;  StaticCode.getNum();
  • 在命令行中运行:java StaticDemo

类所有内容加载顺序及内存中的存储位置

语句分析

Person p = new Person(“Shawn”,20);

  1. 在栈内存中,开辟main函数的空间,建立main函数的变量p。
  2. 加载类文件:因为new要用到Person.class,所以要先从硬盘中找到Person.class类文件,并加载到内存中。
    • 加载类文件时,除了非静态成员变量不会被加载,其他的都会被加载。
    • 静态成员变量(类变量)------>方法区的非静态部分
    • 静态方法------>方法区的静态部分
    • 静态代码块------>方法区的静态部分
    • 构造代码块------>方法区的静态部分
    • 注意:在Person.class文件加载时,静态方法和非静态方法都会被加载到方法区中,只不过要调用非静态方法时需要先实例化一个对象,对象才能调用非静态方法。如果让类中所有的非静态方法都随着对象的实例化而建立一次,那么会大量消耗内存资源,所以才会让所有对象共享这些非静态方法
  3. 执行类中的静态代码块:如果有的话,对Person.class类进行初始化。
  4. 开辟空间:在堆内存中开辟空间,分配内存地址。
  5. 默认初始化:在堆内存中建立对象的特有属性,并进行默认初始化。
  6. 显式初始化:对属性进行显示初始化。
  7. 构造代码块:执行类中的构造代码块,对对象进行构造代码块初始化。
  8. 构造函数初始化:对对象进行对应的构造函数初始化。
  9. 将内存地址赋值给栈内存中的变量p。

p.setName(“Feng”);

  1. 在栈内存中开辟setName()方法的空间,里面有:对象的引用this,临时变量name
  2. 将p的值赋值给this,this就指向了堆中调用该方法的对象
  3. 将"Feng"赋值给临时变量name
  4. 将临时变量的值赋值给this指向的name

Person.showCountry();

  1. 在栈内存中,开辟showCountry()方法的空间,里面有:类名的引用Person
  2. Person指向方法区中的Person类的静态方法区的地址
  3. 调用静态方法区中的country,并输出
    • 注意:
    • 要想使用类中的成员,必须调用
    • 通过什么调用?
    • 类名,this,super。

静态代码块、构造代码块和构造函数的区别

静态代码块:用于给类初始化,类加载时就会被加载执行,只执行一次。

构造代码块:用于给对象初始化,只要建立对象该部分都会执行,优先于构造函数执行,每个对象只执行一次。

构造函数:给对象的对象初始化,建立对象是,选择相应的构造函数初始化对象

创建对象时,三者被加载执行顺序是:静态代码块--->构造代码块--->构造函数

   1: class Person 

   2: {

   3:     //非静态变量,对象建立时存在于堆中

   4:     private int age = 0;

   5:     //静态变量,类加载时存在于方法区的静态部分

   6:     private static String country = "cn";

   7:     //静态代码块,类加载时,存在于方法区的静态部分

   8:     static

   9:     {

  10:         System.out.println("class load");

  11:     }

  12:     //构造代码块,类加载时,存在于方法区的静态部分

  13:     {

  14:         System.out.println("object load");

  15:     }

  16:  

  17:     Person(int age)

  18:     {

  19:         this.age = age;

  20:     }

  21:  

  22:     //静态方法,类加载时存在于方法区的静态部分

  23:     public static void showCountry()

  24:     {

  25:         System.out.println(country);

  26:     }

  27:     //非静态方法,类加载时存在于方法区的非静态部分

  28:     void print()

  29:     {

  30:         System.out.println(age);

  31:     }

  32: }

总结

类加载

下列被加载:

  • 类变量(静态成员变量)
  • 静态和非静态方法
  • 静态代码块和构造代码块

下列被执行:

  • 类变量的默认初始化和显式初始化
  • 静态代码块

对象加载

下列被加载:

  • 如果类第一次被用到,则先加载上面类的相关内容
  • 非静态成员变量

下列被执行:

  • 非静态成员变量的默认初始化和显式初始化
  • 如果类第一次被用到,则先执行上面类的相关内容
  • 构造代码块
  • 构造函数

存储位置

Java笔记(十二)……类中各部分加载顺序及存放位置问题的更多相关文章

  1. Java 类中各成分加载顺序 和 内存中的存放位置

    参加一个笔试,有一个关于类的静态代码块.构造代码块.构造函数的执行顺序的问题.不太清楚,网上百度了一下.在这里记录一下. 一.什么时候会加载类?使用到类中的内容时加载:有三种情况1.创建对象:new ...

  2. java类中属性的加载顺序,以及内存分配情况介绍

    看下面例子及说明: /** 假如有外部类调用了该类,代码为:new StaticTest(); 那么下面是类属性的加载顺序 */ public class StaticTest{ public int ...

  3. 详解web.xml中元素的加载顺序

    一.背景 最近在项目中遇到了启动时出现加载service注解注入失败的问题,后来经过不懈努力发现了是因为web.xml配置文件中的元素加载顺序导致的,那么就抽空研究了以下tomcat在启动时web.x ...

  4. 如果你还不知道如何控制springboot中bean的加载顺序,那你一定要看此篇

    1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功 ...

  5. 服务器启动时Webapp的web.xml中配置的加载顺序

    一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...

  6. 服务器启动时Webapp的web.xml中配置的加载顺序(转载)

    一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...

  7. SpringBoot中的bean加载顺序

    https://www.dazhuanlan.com/2019/10/22/5daebc5d16429/ 最近在做传统Spring项目到SpringBoot项目迁移过程中,遇到了一些bean加载顺序的 ...

  8. Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

  9. 2、手把手教你Extjs5(二)项目中文件的加载过程

    上一节中用sencha工具自动创建了一个项目,并且可以在浏览器中查看.现在我们来看看js类加载过程.如下图所示: 1、首先:浏览器中输入 localhost:1841 ,调用 index.html; ...

随机推荐

  1. [Linux]root默认密码问题

    Linux/Ubuntu root默认密码问题   Ubuntu安装后root是没有默认的密码的,因为你还没给root设置密码,你第一个 user 是在 admin 组,他可以给 root 设置密码, ...

  2. Java基础知识学习

    1.什么是Java编程语言 Java是:一种编程语言.一种开发环境.一种应用环境.一种部署环境 2.Java编程语言的主要目标 (1)提供一种解释环境为:提高开发速度.代码可移植性.使用户能运行不止一 ...

  3. 一步步学习NHibernate(3)——NHibernate增删改查

    请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们配置了以下NHibernate的运行环境, 并介绍了NHibernate的中两个非常中重要的接口"I ...

  4. 全面认识UML类图元素

    本节和大家一起学习一下UML类图元素,类图能出色地表示继承与合成关系.为了将UML类图作为一种高效的沟通工具使用,开发者必须理解如何将类图上出现的元素转换到Java中.请看本节详细介绍. 全面认识UM ...

  5. C# - implicit, explicit

    如果类型直接没有继承关系,也没有共享接口,想在这两个类型之间进行转换,就必须重载转换运算符. 此时需要关键字implicit和explicit. 下面定义了类型ConvClass1和ConvClass ...

  6. Java连接MySQl数据库实现代码

    1. 获取数据库连接和查询代码 package connectionmysql; import java.sql.Connection; import java.sql.DriverManager; ...

  7. [转载]C# 中对html 标签过滤

    private string FilterHTML(string html) { System.Text.RegularExpressions.Regex regex1 = new System.Te ...

  8. Note8 开机提示:secSetupWized 已停止

    情况分析: 1.要么没有双清2.要么是删除了系统内置服务 恢复后的向导 这个如果正常情况下是 弹出 选择所在地区语言/联系方式/系统设置 此情景一般出现在 刷机后/恢复默认出厂设置后. 解决办法: 刷 ...

  9. Linux巡检

    # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostn ...

  10. c#使用XSLT将xml文档转换为html文档

    需要引用下面的命名空间: using System.Xml; using System.Xml.Xsl; 方法实现: public static string ConvertXML(XmlDocume ...