静态代码块&非静态代码块&构造函数

   总结:静态代码块总是最先执行。非静态代码块跟非静态方法一样,跟对象有关。只不过非静态代码块在构造函数之前执行。父类非静态代码块、构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非静态代码块和构造函数。 

  相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,一般在代码块中对一些static变量进行赋值。

  不同点:静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。

    静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。

Example1:

    1. public class PuTong {
    2. public PuTong(){
    3. System.out.print("默认构造方法!-->");
    4. }
    5. //非静态代码块
    6. {
    7. System.out.print("非静态代码块!-->");
    8. }
    9. //静态代码块
    10. static{
    11. System.out.print("静态代码块!-->");
    12. }
    13. public static void test(){
    14. {
    15. System.out.println("普通方法中的代码块!");
    16. }
    17. }
    18. }
    19. //测试类
    20. public class TestClass {
    21. /**
    22. * 区别两次new静态与非静态代码块执行情况
    23. */
    24. public static void main(String[] args) {
    25. PuTong c1 = new PuTong();
    26. c1.test();
    27. PuTong c2 = new PuTong();
    28. c2.test();
    29. }
    30. }
    31. /*
    32. 运行输出结果是:
    33. 静态代码块!-->非静态代码块!-->默认构造方法!-->普通方法中的代码块!
    34. 非静态代码块!-->默认构造方法!-->普通方法中的代码块!
    35. */

Example2:

  1. package tags;
  2. public class Child extends Father{
  3. static {
  4. System.out.println("child-->static");
  5. }
  6. private int n = 20;
  7. {
  8. System.out.println("Child Non-Static");
  9. n = 30;
  10. }
  11. public int x = 200;
  12. public Child() {
  13. this("The other constructor");
  14. System.out.println("child constructor body: " + n);
  15. }
  16. public Child(String s) {
  17. System.out.println(s);
  18. }
  19. public void age() {
  20. System.out.println("age=" + n);
  21. }
  22. public void printX() {
  23. System.out.println("x=" + x);
  24. }
  25. public static void main(String[] args) {
  26. new Child().printX();
  27. }
  28. }
  29. class Father {
  30. static {
  31. //System.out.println("n+"+n);
  32. //当n定义在下面时,会提示Cannot reference a field before it is defined,
  33. //所以必须把n定义移到上面才可以输出
  34. System.out.println("super-->static");
  35. }
  36. public static int n = 10;
  37. public int x = 100;
  38. public Father() {
  39. System.out.println("super‘s x=" + x);
  40. age();
  41. }
  42. {
  43. System.out.println("Father Non-Static");
  44. }
  45. public void age(){
  46. System.out.println("nothing");
  47. }
  48. }

结果:

super-->static

child-->static

Father Non-Static

super‘s x=100

age=0

Child Non-Static

The other constructor

child constructor body: 30

x=200

    父类静态代码块 -> 子类静态代码块-> 父类非静态代码块 -> 父类构造函数-> 子类非静态代码块 -> 子类构造函数

java中,在使用new操作符创建一个类的实例对象的时候,开始分配空间并将成员变量初始化为默认的数值,注意这里并不是指将变量初始化为在变量定义处的初始值,而是给整形赋值0,给字符串赋值null 这一点于C++不同,(student.name = null , student.age = 0 )然后在进入类的构造函数。在构造函数里面,首先要检查是否有this或者super调用,this调用是完成本类本身的构造函数之间的调用,super调用是完成对父类的调用。二者只能出现一个,并且只能作为构造函数的第一句出现。在调用this和super的时候实现程序的跳转,转而执行被调用的this构造函数或者super构造函数。在this和super执行完毕,程序转而执行在类定义的时候进行的变量初始化工作。这个执行完毕,才是构造函数中剩下的代码的执行。

时间: 2024-11-25 10:33:47

静态代码块&非静态代码块&构造函数的相关文章

区分同步代码块、静态同步方法、非静态同步方法的锁

同步代码块.静态同步方法.非静态同步方法的锁分别是: 同步代码块可以使用自定义的Object对象,也可以使用this或者当前类的字节码文件(类名.class): 静态同步方法的锁是当前类的字节码文件(类名.class): 非静态同步方法的锁是this: 证明方法: 两个线程之间实现同步,一个线程使用同步代码块,一个线程使用同步方法. 如果这两个线程同步了,说明了使用的是同一个锁: 创建线程类(以售票为例) /** * @methodDesc 售票线程类 */ public class Threa

java synchronized静态同步方法与非静态同步方法,同步语句块

摘自:http://topmanopensource.iteye.com/blog/1738178 进行多线程编程,同步控制是非常重要的,而同步控制就涉及到了锁. 对代码进行同步控制我们可以选择同步方法,也可以选择同步块,这两种方式各有优缺点,至于具体选择什么方式,就见仁见智了,同步块不仅可以更加精确的控制对象锁,也就是控制锁的作用域,何谓锁的作用域?锁的作用域就是从锁被获取到其被释放的时间.而且可以选择要获取哪个对象的对象锁.但是如果在使用同步块机制时,如果使用过多的锁也会容易引起死锁问题,同

关于静态变量和非静态变量的区别

关于静态变量和非静态变量的区别 静态变量:被static修饰的变量,加载类的时候被创建,不随对象的创建而改变,静态变量位于方法区,类消失对应的变量消失. 非静态变量:不被static修饰的变量,每创建一次对象,就会为变量分配一次内存,存放在堆内存中,对象消失对应的变量消失. JAVA中初始化的顺序: 加载类: 静态变量初始化 静态代码块:[其只能调度静态的,不能调度非静态的] 成员变量 构造代码块 构造方法 普通代码块 原文地址:https://www.cnblogs.com/wangwswan

Java显示的静态初始化和非静态实例初始化

静态初始化只执行一次,实例初始化每次创建实例都会执行. 1.创建一个Spoon类: package com.samsung.wx; public class Spoon { static { System.out.println("显示的静态初始化"); } { System.out.println("非静态实例初始化"); } public void f1(int i) { System.out.println(i); } } 2.测试代码: package co

java 静态资源,非静态资源,父类子类,构造方法之间的初始化循序

java面试经常被问静态资源,非静态资源,父类子类,构造方法之间的执行顺序.下面添加两个类做个测试 class Parent { // 静态变量 public static String p_StaticField = "父类--静态变量"; // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例) //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化 public String p_Field = "父类--变量"; // 静态初始化块

静态对象与非静态对象

Java静态对象和非静态对象有什么区别?? 静态对象                                                        非静态对象      是类共同拥有的.                                          是类独立拥有的, 内存空间上是固定的                                              空间在各个附属类里面分配 先分配静态对象的空间                   

使用Entity Framework迁移完数据库后,每次修改代码(非模型代码)后都报错。

问题:使用Entity Framework迁移完数据库后,每次修改代码(非模型代码)后都报错: 支持“XXXDbContext”上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269). 这时如果执行 Add-Migration 生成的迁移代码是空的.于是重新Update-Database,结果却是No pending explicit migrations. 不过这时是不

关于静态变量,静态代码块,非静态变量,构造方法中变量实例化顺序

LuceneUtils.java 1 import java.util.ArrayList; 2 import java.util.List; 3 4 @SuppressWarnings("unused") 5 public class LuceneUtils { 6 private String a = "string";//第四个个实例化,如果这个地方没有给a赋值那么不走这个语句(仅仅是声明). 7 private static Object o = null;

静态代码先于非静态代码

静态代码为什么先于非静态代码 这是因为静态代码是在类加载完毕后执行的,而加载类的顺序是先父类后子类,所以静态代码的执行是先执行父类的,然后执行子类的. 对于非静态变量以及实例初始化块都是在构造函数里的代码执行前执行. 所以静态代码是在类加载后执行,而实例代码是在构造函数执行前执行. 但是当我们显示控制类加载的时候情况有点变化,显示加载可以有关两种方法: 第一种:利用forName方法 当我们查API文档就会发现forName方法有两种形式. 分别如下: public static Class<?