黑马程序员技术交流社区

标题: 静态代码块、构造代码块、构造函数的执行顺序 [打印本页]

作者: 白衣卿相    时间: 2015-7-26 15:06
标题: 静态代码块、构造代码块、构造函数的执行顺序
静态代码块、构造代码块、构造函数的执行顺序一、什么时候会加载类?
使用到类中的内容时加载:有三种情况
1.创建对象:newStaticCode();
2.使用类中的静态成员:StaticCode.num=9;  StaticCode.show();
3.在命令行中运行:java StaticCodeDemo
二、类所有内容加载顺序和内存中的存放位置:

1.Personp=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");  
  
         }   
  
         //main方法
  
         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()


作者: Wqi    时间: 2015-7-26 17:09
静态代码块随着类的加载而执行,且只执行一次。
创建对象,执行构造代码块和构造函数。构造代码块是所有构造函数公有的部分,先执行,然后在执行对应的构造函数。
作者: 飞飞飞丨    时间: 2015-7-26 18:16
学习学习




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2