static block and non-static block(constructor block)

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

  1. public class Foo {
  2. public static void main(String[] args) {
  3. Baz.testAsserts();
  4. Baz.testAsserts();
  5. // Will execute after Baz is initialized.
  6. }
  7. }
  8. class Bar {
  9. static {
  10. Baz.testAsserts();
  11. // Will execute before Baz is initialized!
  12. }
  13. }
  14. class Baz extends Bar {
  15. static int x = 1;
  16. static void testAsserts() {
  17. System.out.println("x is " + x);
  18. x=x+2;
  19. }
  20. }
  • 输出结果

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)

  1. class A {
  2. int x ;
  3. //block num 1
  4. {
  5. x = 1;
  6. System.out.println("block num 1, x is " + x);
  7. }
  8. A() {
  9. x = 3;
  10. System.out.println("constructor block x is " + x);
  11. }
  12. //block num 2
  13. {
  14. x = 2;
  15. System.out.println("block num 2, x is " + x);
  16. }
  17. }
  18. public class Non_staticBlock {
  19. public static void main(String[] args) {
  20. String newLine = System.getProperty("line.separator");
  21. System.out.println("====first time instantiate ====" + newLine);
  22. new A();
  23. System.out.println(" \n====second time instantiate ====" + newLine);
  24. new A();
  25. }
  26. }
  • 输出结果、顺序

====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编译器拷贝到了构造块内.
  1. class A {
  2. int x = 1;
  3. A() {
  4. System.out.println("block num 1, x is " + this.x);
  5. this.x = 2;
  6. System.out.println("block num 2, x is " + this.x);
  7. this.x = 3;
  8. System.out.println("constructor x is " + this.x);
  9. }
  10. }

静态代码块 static block

  1. class AA {
  2. AA() {
  3. x = 3;
  4. System.out.println("constructor x is " + x);
  5. }
  6. static int x = 1;
  7. //block num 1
  8. static {
  9. System.out.println("static block num 1 , x is " + x);
  10. }
  11. //block num 2
  12. static {
  13. x = 2;
  14. System.out.println("static block num 2 , x is " + x);
  15. }
  16. static void print() {
  17. System.out.println("static method");
  18. }
  19. }
  20. public class StaticBlock {
  21. static {
  22. System.out.println("==== first ====");
  23. }
  24. public static void main(String[] args) {
  25. String newLine = System.getProperty("line.separator");
  26. System.out.println("====AA class init ====" + newLine);
  27. // class init
  28. AA.print();
  29. System.out.println(" \n====fisrt time instantiate AA====" + newLine);
  30. new AA();
  31. System.out.println(" \n====sencond time instantiate AA====" + newLine);
  32. new AA();
  33. }
  34. }
  • 输出结果、顺序

==== 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 文件如下
  1. class AA {
  2. static int x = 1;
  3. AA() {
  4. x = 3;
  5. System.out.println("constructor x is " + x);
  6. }
  7. static void print() {
  8. System.out.println("static method");
  9. }
  10. static {
  11. System.out.println("static block num 1 , x is " + x);
  12. x = 2;
  13. System.out.println("static block num 2 , x is " + x);
  14. }
  15. }

联合看一下

  1. class AAA {
  2. int x;
  3. //block num 1
  4. {
  5. x = 1;
  6. System.out.println("non-static block num 1 x is " + x);
  7. }
  8. AAA() {
  9. x = 3;
  10. System.out.println("constructor x is " + x);
  11. }
  12. //block num 2
  13. {
  14. x = 2;
  15. System.out.println("non-static block num 2 x is " + x);
  16. }
  17. // The static block only gets called once,when the class itself is initialized,
  18. // no matter how many objects of that type you create
  19. static {
  20. System.out.println("static block");
  21. }
  22. //Gets called every time an instance of the class is constructed.
  23. //the non-static block is actually copied by the Java compiler into every constructor the class has (source).
  24. //So it is still the constructor's job to initialize fields.
  25. //to understand "actually " , find the result in the .class file of A.class
  26. {
  27. System.out.println("non-static block");
  28. }
  29. }
  30. public class BlockSample {
  31. public static void main(String[] args) {
  32. String newLine = System.getProperty("line.separator");
  33. System.out.println("====first time instantiate AAA ====" + newLine);
  34. new AAA();
  35. System.out.println(" \n====second time instantiate AAA ====" + newLine);
  36. new AAA();
  37. }
  38. }
  • 输出结果、顺序

====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 文件
  1. class AAA {
  2. int x = 1;
  3. AAA() {
  4. System.out.println("non-static block num 1 x is " + this.x);
  5. this.x = 2;
  6. System.out.println("non-static block num 2 x is " + this.x);
  7. System.out.println("non-static block");
  8. this.x = 3;
  9. System.out.println("constructor x is " + this.x);
  10. }
  11. static {
  12. System.out.println("static block");
  13. }
  14. }

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. 浅谈JavaScript的面向对象程序设计(四)

    本文继续讲解JavaScript的面向对象程序设计.继承是面向对象语言中的一个基本概念,面向对象语言支持两种继承实现方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.但是在 ...

  2. windows服务管理操作

    服务程序是windows上重要的一类程序,它们虽然不与用户进行界面交互,但是它们对于系统有着重要的意义.windows上为了管理服务程序提供了一个特别的程序:服务控制管理程序,系统上关于服务控制管理的 ...

  3. .NET使用Office Open XML导出超大数量数据到 Excel

    我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原始的HTML拼接(将需要导出的数据拼接成TABLE标签)到后来happy的使用开源的NPOI, EPPlus等开源组件导出EX ...

  4. Ubuntu 设置内核版本的GRUB默认启动

    注:我只是一只小小的搬运工.这篇文章内容摘自: https://www.calazan.com/how-to-set-an-older-kernel-version-as-the-default-in ...

  5. 异常笔记--java编程思想

    开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出 ...

  6. Tomcat多个项目部署,通过Nginx反向代理分别配置二级域名的流程

    购买域名.示例:example.com 设置多个二级域名.如图: 配置tomcat文件: 修改tomcat/conf目录下的server.xml文件: 如下配置配置了3个容器,使用三个不同的端口. 请 ...

  7. bootstrap-table操作之“删除”

    最近在做一个新的后台管理系统,在对数据进行操作时需要写一个"删除"功能,如图所示: 下面我来描述一下实现过程中出现的bug以及解决方法: 1.href值为空(href=" ...

  8. CTF---Web入门第九题 FALSE

    FALSE分值:10 来源: iFurySt 难度:易 参与人数:4567人 Get Flag:2144人 答题人数:2157人 解题通过率:99% PHP代码审计 hint:sha1函数你有认真了解 ...

  9. UVALive3882-And Then There Was One-约瑟夫问题-递推

    And Then There Was One Time limit: 3.000 seconds Let's play a stone removing game. Initially, n ston ...

  10. c++extern关键字详解

    1 基本解释 :extern可以置于变量或者函数 前,以标示变量或者函数的定义在别的文件中 ,提示编译器遇到此变量和函数时在其他模块中寻找其定义 .此外extern也可用来进行链接指定. 也就是说ex ...