static block and non-static block(constructor block)

想来想去,先来一题比较好

public class Foo {
public static void main(String[] args) {
Baz.testAsserts();
Baz.testAsserts();
// Will execute after Baz is initialized.
}
} class Bar {
static {
Baz.testAsserts();
// Will execute before Baz is initialized!
}
} class Baz extends Bar {
static int x = 1; static void testAsserts() { System.out.println("x is " + x);
x=x+2;
} }
  • 输出结果

x is 0

x is 1

x is 3

  • 分析
  1. Invoking Baz.testAsserts() cause Baz to be initialized
  2. default value int x=0;
  3. Before Baz initialize , Bar must be initialized
  4. Bar's static initializer again invoking Baz.testAsserts()
  5. so x is 0 , then x+2 , x=2
  6. go on initializing Baz , init x = 1;
  7. Invoking Baz.testAsserts() x = 1 , so x is 1;

Java类初始化顺序

父类静态变量 ——>父类静态代码块——>子类静态代码块——>父类非静态变量 ——>

父类非静态代码块——>父类构造函数 ——>子类非静态变量——>子类非静态代码块——>

子类构造函数

非静态代码块 non-static block(constructor block)

class A {

    int x ;

    //block num 1
{
x = 1;
System.out.println("block num 1, x is " + x);
} A() {
x = 3;
System.out.println("constructor block x is " + x);
} //block num 2
{
x = 2;
System.out.println("block num 2, x is " + x);
} } public class Non_staticBlock { public static void main(String[] args) { String newLine = System.getProperty("line.separator"); System.out.println("====first time instantiate ====" + newLine);
new A(); System.out.println(" \n====second time instantiate ====" + newLine);
new A();
} }
  • 输出结果、顺序

====first time instantiate ====

block num 1, x is 1

block num 2, x is 2

constructor x is 3

====second time instantiate ====

block num 1, x is 1

block num 2, x is 2

constructor x is 3

  • 非静态代码块被java编译器拷贝到了构造块内,所以称为"constructor block"也是可以的,所以每次 new 构造函数也都执行
  • .class 文件如下, 非静态代码块被java编译器拷贝到了构造块内.
class A {
int x = 1; A() {
System.out.println("block num 1, x is " + this.x);
this.x = 2;
System.out.println("block num 2, x is " + this.x);
this.x = 3;
System.out.println("constructor x is " + this.x);
}
}

静态代码块 static block

class AA {

    AA() {
x = 3;
System.out.println("constructor x is " + x);
} static int x = 1; //block num 1
static {
System.out.println("static block num 1 , x is " + x);
} //block num 2
static {
x = 2;
System.out.println("static block num 2 , x is " + x);
} static void print() {
System.out.println("static method");
}
} public class StaticBlock {
static {
System.out.println("==== first ====");
} public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====AA class init ====" + newLine);
// class init
AA.print(); System.out.println(" \n====fisrt time instantiate AA====" + newLine); new AA();
System.out.println(" \n====sencond time instantiate AA====" + newLine);
new AA();
}
}
  • 输出结果、顺序

==== first ====

====AA class init ====

static block num 1 , x is 1

static block num 2 , x is 2

static method

==== first time instantiate AA ====

constructor x is 3

==== second time instantiate AA ====

constructor x is 3

  • 由于JVM在加载类时会执行静态代码块,且只会执行一次. 本例静态引用AA.print(); 触发类初始化
  • 静态代码块先于主方法执行,本例优先打印first
  • 更多内容搜索jvm类加载
  • .class 文件如下
class AA {
static int x = 1; AA() {
x = 3;
System.out.println("constructor x is " + x);
} static void print() {
System.out.println("static method");
} static {
System.out.println("static block num 1 , x is " + x);
x = 2;
System.out.println("static block num 2 , x is " + x);
}
}

联合看一下

class AAA {
int x; //block num 1
{
x = 1;
System.out.println("non-static block num 1 x is " + x);
} AAA() {
x = 3;
System.out.println("constructor x is " + x); } //block num 2
{
x = 2;
System.out.println("non-static block num 2 x is " + x);
} // The static block only gets called once,when the class itself is initialized,
// no matter how many objects of that type you create
static {
System.out.println("static block");
} //Gets called every time an instance of the class is constructed.
//the non-static block is actually copied by the Java compiler into every constructor the class has (source).
//So it is still the constructor's job to initialize fields.
//to understand "actually " , find the result in the .class file of A.class
{
System.out.println("non-static block");
}
} public class BlockSample { public static void main(String[] args) { String newLine = System.getProperty("line.separator"); System.out.println("====first time instantiate AAA ====" + newLine);
new AAA(); System.out.println(" \n====second time instantiate AAA ====" + newLine);
new AAA(); }
}
  • 输出结果、顺序

====first time instantiate AAA ====

static block

non-static block num 1 x is 1

non-static block num 2 x is 2

non-static block

constructor x is 3

====second time instantiate AAA ====

non-static block num 1 x is 1

non-static block num 2 x is 2

non-static block

constructor x is 3

  • .class 文件
class AAA {
int x = 1; AAA() {
System.out.println("non-static block num 1 x is " + this.x);
this.x = 2;
System.out.println("non-static block num 2 x is " + this.x);
System.out.println("non-static block");
this.x = 3;
System.out.println("constructor x is " + this.x);
} static {
System.out.println("static block");
}
}

java基础-静态,非静态(构造)代码块,类加载的更多相关文章

  1. java基础8 构造函数和构造代码块

    一.构造函数 1 构造函数的作用 给对应的对象进行初始化. 2 构造函数的格式 修饰符 函数名(形式参数){ //函数名就是类名 函数体 } 举例说明: class Perosn{ private i ...

  2. 黑马程序员——JAVA基础之构造函数,构造代码块

    ------- android培训.java培训.期待与您交流! ---------- 构造函数特点: 1.  函数名与类名相同 2.  不用定义返回值类型 3.  不可以写return语句 构造函数 ...

  3. java静态代码块、静态方法、静态变量、构造代码块、普通代码块

    一.静态代码块 1.在java类中(方法中不能存在静态代码块)使用static关键字和{}声明的代码块: public class CodeBlock{ static{ System.out.prin ...

  4. Java 基础 面向对象之关键字内部类代码块修饰符

    final final概念 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后 ...

  5. 【Java基础】继承中的代码块和构造方法的执行顺序探索

    本文讲述有关一个类的静态代码块,构造代码块,构造方法的执行流程问题.首先来看一个例子 /** * Created by lili on 15/10/19. */ class Person{ stati ...

  6. java基础-表达式,语句和代码块

    浏览以下内容前,请点击并阅读 声明 表达式 表达式由变量,操作符和方法调用组成,表达式的返回值类型由表达式中的元素(如操作符,变量等)决定如: cadence = 0 上述代码将返回一个int类型的值 ...

  7. Java类中代码的执行顺序 静态代码块>构造代码块>构造方法

    一:静态代码块 注意是代码块,不是静态函数.函数要调用才执行,代码块加载就执行,一般是静态变量的声明与初始化.被static修饰的代码块(赋值.输出操作等).类中静态语句块仅在类加载时被执行一次 如 ...

  8. 【Java基础】2、Java中普通代码块,构造代码块,静态代码块区别及代码示例

    Java中普通代码块,构造代码块,静态代码块区别及代码示例.Java中普通代码块,构造代码块,静态代码块区别及代码示例 执行顺序:静态代码块>静态方法(main方法)>构造代码块>构 ...

  9. java基础之静态代码块,局部代码块,构造代码块区别。

    java中有几种常见的代码块,那怎样区别他们呢? 这里就这些问题,浅谈下我个人的理解. 1.局部代码块 局部代码块,又叫普通代码块.它是作用在方法中的代码块.例如: public void show( ...

随机推荐

  1. sso示例代码

    个人写的一个关于在ASP.NET 中如何实现SSO单点登录,这可能也是.NET实现大型互联网项目的第一步要解决的问题.已经放到GitHub上供大家参考.https://github.com/bidia ...

  2. C#学习笔记-迭代器模式

    什么是迭代器模式? 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 何时使用迭代器模式? 当需要访问一个聚合对象,而且不管这些对象是什么都需要 ...

  3. Modelsim独立仿真Vivado Clocking Wizard IP Core

    工欲善其事,必先利其器.在使用Vivado自带的仿真软件仿真的时候,相对于更优秀的仿真工具Modelsim,效率低了很多,为了更高效的开发,我尝试着用Vivado级联Modelsim仿真,但是级联后还 ...

  4. Git知识总览(三) 分支的创建、删除、切换、合并以及冲突解决

    前两篇博客集中的聊了git的一些常用命令,具体请参见<Git知识总览(一) 从 git clone 和 git status 谈起>.<Git知识总览(二) git常用命令概览> ...

  5. 用json方法来作深拷贝应该知道的一点东西!

    之前写js比较多的的时候也写过深拷贝,浅拷贝,继承啥的,还有自定义的监听事件.然而过了很久都忘了. 最近在项目上用的深拷贝都是 b = JSON.parse( JSON.stringify(a) ) ...

  6. async/await 执行顺序详解

    随着async/await正式纳入ES7标准,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 ...

  7. HDU1114Piggy-Bank(完全背包)

    Piggy-Bank Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  8. HDU--1213并查集

    题目传送门:HDU--1213 //题意:ignatius过生日,客人来到,他想知道他需要准备多少张桌子.然而一张桌子上面只能坐上相互熟悉的人, //其中熟悉可定义成为A与B认识,B与C认识,我们就说 ...

  9. 去除FineReport报表点击单元格时出现的黑框

    选择模版->模版web属性 添加加载结束事件,具体代码如下 $("td").bind("click",function(){return false;}) ...

  10. spring是什么???

    1.是一个容器 2.用于降低代码间的耦合度3.根据不同的代码采用ioc和aop两种技术解耦合...