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
  
三、静态代码块、构造代码块和构造函数的区别
静态代码块:用于给类初始化,类加载时就会被加载执行,只加载一次。
构造代码块:用于给对象初始化的。只要建立对象该部分就会被执行,且优先于构造函数。
构造函数:  给对应对象初始化的,建立对象时,选择相应的构造函数初始化对象。
 创建对象时,三者被加载执行顺序:静态代码块--->构造代码块--->构造函数
 
//利用代码进行测试 例题:06--06:StaticCodeDemo.java

[java] view plain copy

  1. class Person
  2. {
  3. private String name;
  4. private int age=0;
  5. private static String country="cn";
  6. Person(String name,int age)
  7. {
  8. this.name=name;
  9. this.age=age;
  10. }
  11. static
  12. {
  13. System.out.println("静态代码块被执行");
  14. }
  15. { System.out.println(name+"..."+age);}
  16. public void setName(String name)
  17. {
  18. this.name=name;
  19. }
  20. public void speak()
  21. {
  22. System.out.println(this.name+"..."+this.age);
  23. }
  24. public static void showCountry()
  25. {
  26. System.out.println("country="+country);
  27. }
  28. }
  29. class StaticDemo
  30. {
  31. static
  32. {
  33. System.out.println("StaticDemo 静态代码块1");
  34. }
  35. public static void main(String[] args)
  36. {
  37. Person p=new Person("zhangsan",100);
  38. p.setName("lisi");
  39. p.speak();
  40. Person.showCountry();
  41. }
  42. static
  43. {
  44. System.out.println("StaticDemo 静态代码块2");
  45. }
  46. }

输出结果:
 StaticDemo 静态代码块1
 StaticDemo 静态代码块2
 静态代码块被执行
 null...0    //构造代码块
 lisi...100  //speak()
 country=cn  //showCountry()

时间: 2024-10-12 09:11:16

Java 类中各成分加载顺序 和 内存中的存放位置的相关文章

java类中各成分的加载顺序跟内存中的存放位置-----转载

1 参加一个笔试,有一个关于类的静态代码块.构造代码块.构造函数的执行顺序的问题.不太清楚,网上百度了一下.在这里记录一下. 2 3 一.什么时候会加载类? 4 使用到类中的内容时加载:有三种情况 5 1.创建对象:new StaticCode(); 6 2.使用类中的静态成员:StaticCode.num=9; StaticCode.show(); 7 3.在命令行中运行:java StaticCodeDemo 8 9 二.类所有内容加载顺序和内存中的存放位置: 10 利用语句进行分析. 11

Java类实例化时候的加载顺序

面试试题中经常考到此问题,现在做进一步的总结: public class Student { public Student(String name){ System.out.println(name); } } // 父类 public class FuClass { private static Student student=new Student("父类静态变量"); private Student student1=new Student("父类非静态变量"

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

看下面例子及说明: /** 假如有外部类调用了该类,代码为:new StaticTest(); 那么下面是类属性的加载顺序 */ public class StaticTest{ public int dsd=2;//第3 //多个对象会有多次分配内存 public awds() { int sdsfsd=2;//第4 //多个对象会有多次分配内存 } //静态代码块 static{ System.out.println("静态代码块正在加载...");//第1 } public st

(转)java类到底是如何加载并初始化的?

Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处,请多多谅解并欢迎各位能够给予批评指正,提前谢谢各位了. 1. Java虚拟机加载.class过程 虚拟机把Class文件加载到内存,然后进行校验,解析和初始化,最终形成java类型,这就是虚拟机的类加载机制.加载,验证,准备,初始化这5个阶段的顺序是确定的, 类的加载过程,必须按照这种顺序开始.这些

java类到底是如何加载并初始化的?

Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处,请多多谅解并欢迎各位能够给予批评指正,提前谢谢各位了. 1. Java虚拟机加载.class过程 虚拟机把Class文件加载到内存,然后进行校验,解析和初始化,最终形成java类型,这就是虚拟机的类加载机制.加载,验证,准备,初始化这5个阶段的顺序是确定的, 类的加载过程,必须按照这种顺序开始.这些

jvm内存模型,java类从编译到加载到执行的过程,jvm内存分配过程

一.jvm内存模型 JVM 内存模型主要分为堆.程序计数器.方法区.虚拟机栈和本地方法栈 1.堆 1.1.堆是 JVM 内存中最大的一块内存空间. 1.2.该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中. 1.3.堆被划分为新生代和老年代,新生代又被进一步划分为 Eden 和 Survivor 区,最后 Survivor 由 From Survivor 和 To Survivor 组成. 2.程序计数器(Program Counter Register) 程序计数器是一块很小的内存

SpringMVC项目中web.xml中的节点加载顺序问题

SpringMVC项目中web.xml中的节点加载顺序问题,之前以为web.xml中就是一些配置信息,和节点的顺序没有关系,后来才发现初始化时的加载顺序是和节点的顺序相关的. 完整的web.xml文件内容: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns=&quo

Eclipse中使用Tomcat加载项目在浏览器中访问的时候JS和CSS等静态文件无法加载的问题

首先,我的Eclipse是引用外部的Tomcat 引用外部Tomcat会在左侧生成一个Server文件夹,相当于复制了一份Tomcat到Eclipse的安装目录里 具体Tomcat所在目录可以在这进行查看 双击Tomcat服务,会打开一个窗口,然后点击Open launch configuration,可打开配置窗口,在这里可以查看到具体服务所在位置. 接下来步入正题,正如题目所说,Eclipse中使用Tomcat加载项目在浏览器中访问的时候JS和CSS等静态文件无法加载,如图 仔细看下路径,会

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

一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个ServletContext(servlet上下文),这个web项目的所有部分都将共享这个上下文. 3.容器将<context-param>转换为键值对,并交给servletContext. 4.容器创建<listener>中的类实例,创建监听器. 二  Load-on-startup Lo