黑马程序员Java教程:静态代码块
- 格式:docx
- 大小:54.22 KB
- 文档页数:1


Java中静态代码块,代码块,构造⽅法优先级、区别及代码⽰例在项⽬中遇到了代码块的知识点,跑了下测试,写下结论代码优先级:静态代码块 -> 构造代码块 -> 构造⽅法多个代码块优先级,按照“先定义的代码先执⾏,后定义的代码后执⾏”原则执⾏静态代码块只执⾏⼀次构造代码块在类每次创建对象时都会执⾏静态代码块不能存在于任何⽅法体内1.测试⼀1public class CodeBlock01 {2 {3 System.out.println("普通代码块1");4 }5static {6 System.out.println("静态代码块");7 }89public CodeBlock01() {10 System.out.println("构造⽅法");11 }1213 {14 System.out.println("普通代码块2");15 }16 }1 @Test public void testStaticCode(){2new CodeBlock01();3new CodeBlock01();4 }执⾏结果:静态代码块普通代码块1普通代码块2构造⽅法普通代码块1普通代码块2构造⽅法结论:1. 优先级:静态代码块 -> 代码块 -> 构造⽅法2. 静态代码块只会执⾏⼀次3. 代码块会在类每次创建对象的时候都创建,就是每次构造⽅法前都会执⾏2.测试⼆1public class CodeBlock02 {2 {3 System.out.println("普通代码块01");4 }56 {7 System.out.println("普通代码块02");8 }910public CodeBlock02(){11 System.out.println("构造⽅法");12 }13 }1 @Test public void testCodeBlock(){2new CodeBlock02();3 }执⾏结果:普通代码块01普通代码块02构造⽅法结论:代码块执⾏顺序,按照“先定义的代码先执⾏,后定义的代码后执⾏”原则。
java中静态变量,静态代码块,静态⽅法,实例变量,匿名代码块等的加载顺序⼀.在Java中,使⽤”{}”括起来的代码称为代码块,代码块可以分为以下四种:1.普通代码块:就是类中⽅法的⽅法体public void xxx(){//code}2.构造块:⽤{}裹起来的代码⽚段,构造块在创建对象时会被调⽤,每次创建对象时都会被调⽤,并且优先于类构造函数执⾏。
构造块中定义的变量是局部变量。
{//code}3.静态块:⽤static{}裹起来的代码⽚段,只会被执⾏⼀次(第⼀次加载此类时执⾏,⽐如说⽤Class.forName("")加载类时就会执⾏static block),静态块优先于构造块执⾏。
static{//code}4.同步代码块:使⽤synchronized(obj){}裹起来的代码块,在多线程环境下,对共享数据进⾏读写操作是需要互斥进⾏的,否则会导致数据的不⼀致性。
常见的是synchronized⽤来修饰⽅法,其语义是任何线程进⼊synchronized需要先取得对象锁如果被占⽤了,则阻塞,实现了互斥访问共享资源。
⽽synchronized也是有代价的。
⼀个常见的场景是,⼀个冗长的⽅法中,其实只有⼀⼩段代码需要访问共享资源,这时使⽤同步块,就只将这⼩段代码裹在synchronized block,既能够实现同步访问,也能够减少同步引⼊的开销。
同步代码块须写在⽅法中。
synchronized(obj){//code}public class test { //1.第⼀步,准备加载类public static void main(String[] args) {new test(); //4.第四步,new⼀个类,但在new之前要处理匿名代码块}static int num = 4; //2.第⼆步,静态变量和静态代码块的加载顺序由编写先后决定{num += 3;System.out.println("b"); //5.第五步,按照顺序加载匿名代码块,代码块中有打印}int a = 5; //6.第六步,按照顺序加载变量{ // 成员变量第三个System.out.println("c"); //7.第七步,按照顺序打印c}test() { // 类的构造函数,第四个加载System.out.println("d"); //8.第⼋步,最后加载构造函数,完成对象的建⽴}static { // 3.第三步,静态块,然后执⾏静态代码块,因为有输出,故打印aSystem.out.println("a");}static void run() // 静态⽅法,调⽤的时候才加载// 注意看,e没有加载{System.out.println("e");}}12345678910111213141516171819202122232425262728293031321234567891011121314151617181920212223242526272829303132⼀般顺序:静态块(静态变量)——>成员变量——>构造⽅法——>静态⽅法1、静态代码块(只加载⼀次)2、构造⽅法(创建⼀个实例就加载⼀次)3、静态⽅法需要调⽤才会执⾏,所以最后结果没有epublic class Print {public Print(String s){System.out.print(s + " ");}}123456123456public class Parent{public static Print obj1 = new Print("1"); public Print obj2 = new Print("2");public static Print obj3 = new Print("3"); static{new Print("4");}public static Print obj4 = new Print("5"); public Print obj5 = new Print("6");public Parent(){new Print("7");}}123456789101112131415161718192021123456712131415161718192021public class Child extends Parent{static{new Print("a");}public static Print obj1 = new Print("b"); public Print obj2 = new Print("c");public Child (){new Print("d");}public static Print obj3 = new Print("e"); public Print obj4 = new Print("f");public static void main(String [] args){ Parent obj1 = new Child ();Parent obj2 = new Child ();}}123456789101112131415161718192021222312345678910151617181920212223执⾏main⽅法,程序输出顺序为: 1 3 4 5 a b e 2 6 7 c f d 2 6 7 c f d11输出结果表明,程序的执⾏顺序为:如果类还没有被加载:1、先执⾏⽗类的静态代码块和静态变量初始化,并且静态代码块和静态变量的执⾏顺序只跟代码中出现的顺序有关。
静态变量,静态代码块
代码块就是⼀块代码,是⼀对⼤括号括起来的内容
⽅法中:限制变量的⽣命周期
类中⽅法外:
构造代码块:没有关键字修饰,在每次创建对象时,在构造⽅法执⾏前进⾏执⾏
⽤途:可以对成员变量进⾏初始化。
不能对静态常量赋值;
静态代码块:需要使⽤static修饰。
随着类的加载⽽加载执⾏,只有在类加载时加载⼀次
不能对成员变量进⾏初始化。
⽤途:可以对静态成员变量进⾏初始化
可以对静态常量赋值
在创建对象时,可以简单的分为两步:加载类的字节码⽂件,创建对象实例。
加载字节码⽂件会执⾏静态代码块,并且静态代码块只会加载执⾏⼀次
创建对象执⾏静态代码块,构造代码块,构造⽅法
A 静态常量要么直接赋值,要么在静态代码块中赋值
B 常量是归属于对象的,只有在创建对象时才可以赋值,不能放在静态代码块中赋值
C 静态成员变量归属于类,在字节码加载时进⾏加载,可以多次赋值,可以在静态代码块和构造代码块都可以赋值
D 对象成员变量只能在构造代码块中赋值。
【黑马程序员】继承中的构造代码块执行顺序详解在我们Android基础班第八天,相信所有的同学都遇到了这样一道面试题目,题目是请问程序的执行结果,代码如下:class Test2_Extends {public static void main(String[] args) {Zi z = new Zi();}}class Fu {static {System.out.println("静态代码块Fu");}{System.out.println("构造代码块Fu");}public Fu() {System.out.println("构造方法Fu");}}class Zi extends Fu {static {System.out.println("静态代码块Zi");}{System.out.println("构造代码块Zi");}public Zi() {System.out.println("构造方法Zi");}}下面我们循序渐进的来研究一下这个题目,代码块就是用{}括起来的代码,根据代码块的功能、执行顺序和书写位置,我们把代码块分为静态代码块,构造代码块,局部代码块。
静态代码块:书写在成员位置,大括号前面有static关键字,仅随着类的加载执行一次,所以可以在里面一些项目中的初始化的内容。
∙构造代码块:书写在成员位置,每次创建对象的时候构造代码块都会执行一次,而且是在构造方法的内容执行之前执行,所以可以写一些该类里面所有构造方法共性的内容。
∙局部代码块:书写在局部位置(即方法里面),可以尽早的让变量在内存中消失,略微提升一些效率首先执行Zi z = new Zi();创建Zi类对象的时候,必须先加载Zi类的父类Fu,接着加载Zi类,那么Fu类和Zi类中的静态代码块就会随着类的加载而依次执行了,然后程序即将执行Zi类的构造方法,但是在构造方法执行之前必须先执行Zi类的构造代码块,接着执行Zi类的构造方法,由于Zi类的构造方法第一行语句默认都有super(),所以接着将要去执行父类Fu的构造方法,但是在执行Fu的构造方法之前,先执行Fu的构造代码块,然后才能执行Fu的构造方法,执行Fu的这些内容后,才接着执行Zi类构造方法的后续内容。