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

 更新时间:2017年02月21日 10:56:09   投稿:jingxian  
下面小编就为大家带来一篇浅谈Java 类中各成分加载顺序和内存中的存放位置。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、什么时候会加载类?

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

1.创建对象:new StaticCode();

2.使用类中的静态成员:StaticCode.num=9;  StaticCode.show();

3.在命令行中运行:java StaticCodeDemo

二、类所有内容加载顺序和内存中的存放位置

利用语句进行分析:

1.Person p=new Person("zhangsan",20);

该句话所做的事情:

1.在栈内存中,开辟main函数的空间,建立main函数的变量 p。

2.加载类文件:因为new要用到Person.class,所以要先从硬盘中找到Person.class类文件,并加载到内存中。

加载类文件时,除了非静态成员变量(对象的特有属性)不会被加载,其它的都会被加载。

记住:加载,是将类文件中的一行行内容存放到了内存当中,并不会执行任何语句。---->加载时期,即使有输出语句也不会执行。

静态成员变量(类变量)----->方法区的静态部分

静态方法                   ----->方法区的静态部分

静态代码块               ----->方法区的静态部分

非静态方法(包括构造函数)----->方法区的非静态部分 

构造代码块               ----->方法区的静态部分

注意:

在Person.class文件加载时,静态方法和非静态方法都会加载到方法区中,只不过要调用到非静态方法时需要先实例化一个对象,

对象才能调用非静态方法。如果让类中所有的非静态方法都随着对象的实例化而建立一次,那么会大量消耗内存资源,

所以才会让所有对象共享这些非静态方法,然后用this关键字指向调用非静态方法的对象。

3.执行类中的静态代码块:如果有的话,对Person.class类进行初始化。

4.开辟空间:在堆内存中开辟空间,分配内存地址。

5.默认初始化:在堆内存中建立 对象的特有属性,并进行默认初始化。

6.显示初始化:对属性进行显示初始化。

7.构造代码块:执行类中的构造代码块,对对象进行构造代码块初始化。

8.构造函数初始化:对对象进行对应的构造函数初始化。

9.将内存地址赋值给栈内存中的变量p。

2.p.setName("lisi");

1.在栈内存中开辟setName方法的空间,里面有:对象的引用this,临时变量name

2.将p的值赋值给this,this就指向了堆中调用该方法的对象。

3.将"lisi" 赋值给临时变量name。

4.将临时变量的值赋值给this的name。

3.Person.showCountry();

1.在栈内存中,开辟showCountry()方法的空间,里面有:类名的引用Person。

2.Person指向方法区中Person类的静态方法区的地址。

3.调用静态方法区中的country,并输出。

注意:要想使用类中的成员,必须调用。通过什么调用?有:类名、this、super

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

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

构造代码块:用于给对象初始化的。只要建立对象该部分就会被执行,且优先于构造函数。

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

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

class Person 
{ 
  private String name; 
  private int age=0; 
  private static String country="cn";  
  Person(String name,int age) 
  { 
    this.name=name; 
    this.age=age;   
  } 
  static 
  { 
    System.out.println("静态代码块被执行");  
  } 
  { System.out.println(name+"..."+age);  } 
  public void setName(String name) 
  { 
    this.name=name;  
  } 
  public void speak() 
  { 
    System.out.println(this.name+"..."+this.age);   
  } 
  public static void showCountry() 
  { 
    System.out.println("country="+country);  
  } 
} 
class StaticDemo 
{ 
  static 
  { 
    System.out.println("StaticDemo 静态代码块1");   
  } 
  public static void main(String[] args) 
  { 
    Person p=new Person("zhangsan",100); 
    p.setName("lisi"); 
    p.speak(); 
    Person.showCountry();   
  } 
  static 
  { 
    System.out.println("StaticDemo 静态代码块2");   
  }   
} 

输出结果: 

      StaticDemo 静态代码块1 
      StaticDemo 静态代码块2 

静态代码块被执行 

      null...0          //构造代码块 
      lisi...100        //speak() 
      country=cn        //showCountry()  

以上这篇浅谈Java 类中各成分加载顺序和内存中的存放位置就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java和C#输入输出流的方法(详解)

    Java和C#输入输出流的方法(详解)

    下面小编就为大家带来一篇Java和C#输入输出流的方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • 详解Springboot中的异步、定时、邮件任务

    详解Springboot中的异步、定时、邮件任务

    这篇文章主要介绍了Springboot中的异步、定时、邮件任务,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-11-11
  • springBoot项目常用目录解读

    springBoot项目常用目录解读

    这篇文章主要介绍了springBoot项目常用目录解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Java NIO中的零拷贝原理

    Java NIO中的零拷贝原理

    这篇文章主要介绍了Java NIO中的零拷贝原理,零拷贝即Zero-Copy,顾名思义,零拷贝是指的一种非拷贝的方式来减少IO次数的工作方式,零拷贝的作用就是减少IO,提高IO效率,需要的朋友可以参考下
    2023-11-11
  • Spring整合Quartz分布式调度的示例代码

    Spring整合Quartz分布式调度的示例代码

    本篇文章主要介绍了Spring整合Quartz分布式调度的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Spring Boot 与 Kotlin 使用JdbcTemplate连接MySQL数据库的方法

    Spring Boot 与 Kotlin 使用JdbcTemplate连接MySQL数据库的方法

    本文介绍在Spring Boot基础下配置数据源和通过 JdbcTemplate 编写数据访问的示例。感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-01-01
  • JsonProperty及JSONField注解的使用说明

    JsonProperty及JSONField注解的使用说明

    文章介绍了两个常用的Java库注解:Jackson的@JsonProperty和Fastjson的@JSONField,它们用于控制Java对象与JSON数据之间的序列化和反序列化,文章详细说明了这两个注解的常见属性及其使用场景,包括指定属性名、控制字段可见性、设置默认值和标记字段的必需性
    2024-12-12
  • J2EE基础之EJB全面了解

    J2EE基础之EJB全面了解

    下面小编就为大家带来一篇J2EE基础之EJB全面了解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • java中计算字符串长度的方法及u4E00与u9FBB的认识

    java中计算字符串长度的方法及u4E00与u9FBB的认识

    字符串采用unicode编码的方式时,计算字符串长度的方法找出UNICODE编码中的汉字的代表的范围“\u4E00” 到“\u9FBB”之间感兴趣的朋友可以参考本文,或许对你有所帮助
    2013-01-01
  • Java多线程基本概念以及避坑指南

    Java多线程基本概念以及避坑指南

    多线程之于进程的理解,可以类比多进程之于操作系统,多线程指在单个程序中可以同时运行多个不同的线程执行不同的任务,这篇文章主要给大家介绍了关于Java多线程基本概念以及避坑指南的相关资料,需要的朋友可以参考下
    2021-09-09

最新评论