java类中各成分的加载顺序跟内存中的存放位置-----转载
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java类中各成分的加载顺序跟内存中的存放位置-----转载相关的知识,希望对你有一定的参考价值。
1 参加一个笔试,有一个关于类的静态代码块、构造代码块、构造函数的执行顺序的问题。不太清楚,网上百度了一下。在这里记录一下。 2 3 一、什么时候会加载类? 4 使用到类中的内容时加载:有三种情况 5 1.创建对象:new StaticCode(); 6 2.使用类中的静态成员:StaticCode.num=9; StaticCode.show(); 7 3.在命令行中运行:java StaticCodeDemo 8 9 二、类所有内容加载顺序和内存中的存放位置: 10 利用语句进行分析。 11 1.Person p=new Person("zhangsan",20); 12 该句话所做的事情: 13 1.在栈内存中,开辟main函数的空间,建立main函数的变量 p。 14 2.加载类文件:因为new要用到Person.class,所以要先从硬盘中找到Person.class类文件,并加载到内存中。 15 加载类文件时,除了非静态成员变量(对象的特有属性)不会被加载,其它的都会被加载。 16 记住:加载,是将类文件中的一行行内容存放到了内存当中,并不会执行任何语句。---->加载时期,即使有输出语句也不会执行。 17 静态成员变量(类变量) ----->方法区的静态部分 18 静态方法 ----->方法区的静态部分 19 非静态方法(包括构造函数) ----->方法区的非静态部分 20 静态代码块 ----->方法区的静态部分 21 构造代码块 ----->方法区的静态部分 22 23 注意:在Person.class文件加载时,静态方法和非静态方法都会加载到方法区中,只不过要调用到非静态方法时需要先实例化一个对象 24 ,对象才能调用非静态方法。如果让类中所有的非静态方法都随着对象的实例化而建立一次,那么会大量消耗内存资源, 25 所以才会让所有对象共享这些非静态方法,然后用this关键字指向调用非静态方法的对象。 26 27 28 3.执行类中的静态代码块:如果有的话,对Person.class类进行初始化。 29 4.开辟空间:在堆内存中开辟空间,分配内存地址。 30 5.默认初始化:在堆内存中建立 对象的特有属性,并进行默认初始化。 31 6.显示初始化:对属性进行显示初始化。 32 7.构造代码块:执行类中的构造代码块,对对象进行构造代码块初始化。 33 8.构造函数初始化:对对象进行对应的构造函数初始化。 34 9.将内存地址赋值给栈内存中的变量p。 35 2.p.setName("lisi"); 36 1.在栈内存中开辟setName方法的空间,里面有:对象的引用this,临时变量name 37 2.将p的值赋值给this,this就指向了堆中调用该方法的对象。 38 3.将"lisi" 赋值给临时变量name。 39 4.将临时变量的值赋值给this的name。 40 3.Person.showCountry(); 41 1.在栈内存中,开辟showCountry()方法的空间,里面有:类名的引用Person。 42 2.Person指向方法区中Person类的静态方法区的地址。 43 3.调用静态方法区中的country,并输出。 44 注意:要想使用类中的成员,必须调用。通过什么调用?有:类名、this、super 45 46 三、静态代码块、构造代码块和构造函数的区别 47 静态代码块:用于给类初始化,类加载时就会被加载执行,只加载一次。 48 构造代码块:用于给对象初始化的。只要建立对象该部分就会被执行,且优先于构造函数。 49 构造函数: 给对应对象初始化的,建立对象时,选择相应的构造函数初始化对象。 50 创建对象时,三者被加载执行顺序:静态代码块--->构造代码块--->构造函数 51 52 //利用代码进行测试 例题:06--06:StaticCodeDemo.java 53 [java] view plain copy 54 class Person 55 { 56 private String name; 57 private int age=0; 58 private static String country="cn"; 59 Person(String name,int age) 60 { 61 this.name=name; 62 this.age=age; 63 } 64 static 65 { 66 System.out.println("静态代码块被执行"); 67 } 68 { System.out.println(name+"..."+age);} 69 public void setName(String name) 70 { 71 this.name=name; 72 } 73 public void speak() 74 { 75 System.out.println(this.name+"..."+this.age); 76 } 77 public static void showCountry() 78 { 79 System.out.println("country="+country); 80 } 81 } 82 class StaticDemo 83 { 84 static 85 { 86 System.out.println("StaticDemo 静态代码块1"); 87 } 88 public static void main(String[] args) 89 { 90 Person p=new Person("zhangsan",100); 91 p.setName("lisi"); 92 p.speak(); 93 Person.showCountry(); 94 } 95 static 96 { 97 System.out.println("StaticDemo 静态代码块2"); 98 } 99 } 100 101 102 输出结果: 103 StaticDemo 静态代码块1 104 StaticDemo 静态代码块2 105 静态代码块被执行 106 null...0 //构造代码块 107 lisi...100 //speak() 108 country=cn //showCountry()
以上是关于java类中各成分的加载顺序跟内存中的存放位置-----转载的主要内容,如果未能解决你的问题,请参考以下文章