浅谈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 类中各成分加载顺序和内存中的存放位置就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 详解java中继承关系类加载顺序问题

    详解java中继承关系类加载顺序问题 实例代码: /** * Created by fei on 2017/5/31. */ public class SonClass extends ParentClass{ public SonClass(){ System.out.println("SonClass's constructor"); } { System.out.println("SonClass's block");} static { System.out

  • 浅谈Java中父类与子类的加载顺序详解

    复制代码 代码如下: class Parent {    // 静态变量    public static String p_StaticField = "父类--静态变量";    // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例)     //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化    public String p_Field = "父类--变量";    // 静态初始化块    static {        S

  • 详解Java中类的加载顺序

    本文介绍的是Java中类的加载顺序,下面来看看详细的介绍: 1.虚拟机在首次加载Java类时,会对静态初始化块.静态成员变量.静态方法进行一次初始化 2.只有在调用new方法时才会创建类的实例 3.类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始化块部分,然后是父类的构造方法:再执行本类继承的子类的初始化块,最后是子类的构造方法 4.类实例销毁时候,首先销毁子类部分,再销毁父类部分 示例 public class Parent { public static int t = par

  • Java中类的加载顺序剖析(常用于面试题)

    这其实是去年校招时我遇到的一道阿里巴巴的笔试题(承认有点久远了-.-),嗯,如果我没记错的话,当时是作为Java方向的一道选做大题.当然题意没有这么直白,题目只要求你写出程序运行后所有System.out.println的输出结果,其中程序是题目给的,而各个System.out.println的执行顺序不同会导致最后程序输出的结果也不同. 具体的题目我肯定记不清,不过我们可以换个直接的问法,如果类A和类B中有静态变量,静态语句块,非静态变量,非静态语句块,构造函数,静态方法,非静态方法,同时类A

  • Java中类的加载顺序执行结果

    具体代码如下所示: public class Parent { public static int a = parentStaticMethod2(); { System.out.println("父类非静态初始化块"); } static { System.out.println("父类静态初始化块"); } public Parent() { System.out.println("父类的构造方法"); } public static int

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

    一.什么时候会加载类? 使用到类中的内容时加载:有三种情况 1.创建对象:new StaticCode(); 2.使用类中的静态成员:StaticCode.num=9;  StaticCode.show(); 3.在命令行中运行:java StaticCodeDemo 二.类所有内容加载顺序和内存中的存放位置 利用语句进行分析: 1.Person p=new Person("zhangsan",20); 该句话所做的事情: 1.在栈内存中,开辟main函数的空间,建立main函数的变量

  • 浅谈Java类的加载,链接及初始化

    一 类生命周期 Loading Linking(Verification.Preparation.Resolution) Initializing 二 类加载器 1 图解 2 代码 package jvm; public class T002_ClassLoadLevel { public static void main(String[] args) { System.out.println(String.class.getClassLoader()); System.out.println(

  • 浅谈java类和对象

    目录 一.面向对象的描述 二.类和对象的基本概念 三.类定义和使用 1.简单认识类 2.类的定义 3.实例化对象 4.类的三大特性 封装 继承 多态 一.面向对象的描述 面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向对象的设计思路,才形成C++,而由C++产生了Java这门面向对象的编程语言. 但是在面向对象设计之前,广泛采用的是面向过程,面向过程只是针对于自

  • 实例解析JAVA中代码的加载顺序

    Java中代码的加载顺序所能了解的知识点 类的依赖关系 static代码块的加载时间 继承类中构造器的隐式调用 非static的成员变量初始化时间 main方法和static的加载顺序 测试代码如下: public class App { private static App d = new App(); private SubClass t = new SubClass(); static{ System.out.println("App static");//6 } public

  • 浅谈MVC+EF easyui dataGrid 动态加载分页表格

    首先上javascript的代码 <script type="text/javascript"> $(function () { LoadGrid(); }) //加载表格!!! function LoadGrid() { $('#roleGrid').datagrid({ width: 900, striped: true, //交替条纹 fitColumns: true, //防止水平滚动 fit: true,//自动补全 iconCls: "icon-sav

  • Java代码块与代码加载顺序原理详解

    这篇文章主要介绍了Java代码块与代码加载顺序原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本文首先介绍几个基本的名次,然后介绍了三种代码块的特性和使用方法. 在面试大型公司时,如果遇到大型国企或者大的互联网私企,笔试中经常遇到代码块和代码加载顺序的笔试题.这里做一个总结,也方便各位小伙伴飙车不会飘. 名词解释 代码块 由 { } 包起来的代码,称为代码块 静态代码块 由 static { } 包起来的代码,称为静态代码块. 不同类型

  • 如何正确控制springboot中bean的加载顺序小结篇

    1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能. 在一般业务场景,可能你不大关心一个bean是如何被注册进spring容器的.只需要把需要注册进容器的bean声明为@Component即可,spring会自动扫描到这个Bean完成初始化并加载到spring上下文容器. 而当你在项目启动时需要提前做一个业务的初始化工作时,或者你正在开发某个中间

  • 基于springMVC web.xml中的配置加载顺序

    目录 springMVC web.xml中的配置加载顺序 1.Spring上下文环境的配置文件 2.SpringMVC配置文件 加载顺序是 web.xml加载顺序及Spring包扫描注意 1.web.xml文件中配置文件加载顺序 2.SpringMVC配置事务管理时 springMVC web.xml中的配置加载顺序 在这里就不详细说web.xml的文件中的具体配置,就简单说明一下其中配置信息的加载顺序: 在web.xml文件中元素的加载顺序与它们在 web.xml 文件中的先后顺序无关. 加载

  • java 如何查看jar包加载顺序

    目录 查看jar包加载顺序 查看具体的class从哪个jar保重加载的 jar包中类的加载顺序(类名冲突) javac是用来编译*.java文件的 在windows下,多个jar包用分号隔开 查看jar包加载顺序 查看具体的class从哪个jar保重加载的 在JVM启动时,加上如下参数: -verbose:class 然后哦就会有如下输出 [Loaded java.util.regex.Pattern from /Library/Java/JavaVirtualMachines/jdk1.7.0

  • 浅谈Java中static和非static的区别

    关于static和非static变量的区别 1. static 修饰的变量称为类变量或全局变量或成员变量,在类被加载的时候成员变量即被初始化,与类关联,只要类存在,static变量就存在.非static修饰的成员变量是在对象new出来的时候划分存储空间,是与具体的对象绑定的,该成员变量仅为当前对象所拥有的. 2. static修饰的变量在加载的时候先于main方法加载在内存中的数据共享区-------方法区,而非static的变量在加载的时候,是要创建变量才加载在堆内存中的. 3. 一个stat

随机推荐