1.普通变量的初始化

看如下程序
[html] 
class Window{  
public Window(int maker) {  
System.out.println("Window("+maker+")");  
}  
}  
class House{  
Window w1 = new Window(1);  
public House() {  
System.out.println("House()");  
w3 = new Window(33);  
}  
Window w2 = new Window(2);  
void f(){  
System.out.println("f()");  
}  
Window w3 = new Window(3);  
}  
public class Test {  
public static void main(String[] args) {  
House h = new House();  
h.f();  
}  
}  
/*  
结果如下:  
Window(1)  
Window(2)  
Window(3)  
House()  
Window(33)  
f()  
*/  
分析:普通变量在类中的任何方法(包括构造函数)之前初始化(规则一)。
2.静态变量的初始化
[html]  
class Bowl{  
public Bowl(int maker) {  
System.out.println("Bowl("+maker+")");  
}  
void f1(int maker){  
System.out.println("f1("+maker+")");  
}  
}  
class Table{  
static Bowl bowl1 = new Bowl(1);  
static Bowl bowl2 = new Bowl(2);  
public Table() {  
System.out.println("Table()");  
bowl2.f1(1);  
}  
void f2(int maker){  
System.out.println("f2("+maker+")");  
}  
}  
class Cupboard{  
Bowl bowl3 = new Bowl(3);  
static Bowl bowl4 = new Bowl(4);  
static Bowl bowl5 = new Bowl(5);  
public Cupboard() {  
System.out.println("cupboard()");  
bowl4.f1(2);  
}  
void f3(int maker){  
System.out.println("f3("+maker+")");  
}  
}  
public class Test {  
static Table table = new Table();  
static Cupboard cupboard = new Cupboard();  
public static void main(String[] args) {  
System.out.println("creating new cupboard() in main");  
new Cupboard();  
System.out.println("creating new cupboard() in main");  
new Cupboard();  
table.f2(1);  
cupboard.f3(1);  
}  
}  
/*  
结果如下:  
Bowl(1)  
Bowl(2)  
Table()  
f1(1)  
Bowl(4)  
Bowl(5)  
Bowl(3)  
cupboard()  
f1(2)  
creating new cupboard() in main  
Bowl(3)  
cupboard()  
f1(2)  
creating new cupboard() in main  
Bowl(3)  
cupboard()  
f1(2)  
f2(1)  
f3(1)  
*/<span style="color:#ff0000">  
</span>  
分析:
1.首先程序总共有4个类(Bowl,Table,Cupboard,Test),Bowl没有静态变量和静态方法;Table中有静态变量bowl1、bowl2;Cupboard中有普通变量bowl3,静态变量bowl4、bowl5;Test中有静态变量table、cupboard。
2.根据规则:使用static命名的变量或者使用static{}包括起来的区域,都在类被加载时进行初始化(规则二)。
3.虚拟机首先加载Test,需要初始化table变量,加载Table类。Table类中有静态变量bowl1,bowl2,初始化它们,输出"Bowl(1),Bowl(2)",再调用构造函数来new对象,输出"Table(),f1(1)"。然后加载Cupboard类,初始化静态变量bowl4,bowl5,输出"Bowl(4),Bowl(5)",调用构造函数来new对象,首先初始化普通变量bowl3,输出"Bowl(3)",然后构造函数,输出"cupboard(),f1(2)"。
4.执行main方法,先输出"creating new cupboard() in main",执行new Cupboard(),这时静态变量都初始化了,不必继续初始化。初始化一般变量bowl3,输出"bowl3",然后调用构造函数,输出"cupboard(),f1(2)"。在输出"creating new cupboard() in main",同理输出"bowl3,cupboard(),f1(2)",最后继续执行main函数,输出"f2(1),f3(1)"。
3.静态代码块的初始化
[html]  
class Spoon{  
public Spoon(int maker) {  
System.out.println("Spoon("+maker+")");  
}  
static int i;  
static Spoon s = new Spoon(1);  
static{  
System.out.println("static code ");  
i = 47;  
}     
}  
public class Test {  
public static void main(String[] args) {  
new Spoon(2);  
}  
}  
/*  
Spoon(1)  
static code   
Spoon(2)  
*/  
/*  
如果写成  
static{  
System.out.println("static code ");  
i = 47;  
}  
static Spoon s = new Spoon(1);  
结果为:  
static code   
Spoon(1)  
Spoon(2)  
*/  
分析:静态代码块跟静态变量都是类加载时进行初始化的(同等条件下,初始化顺序由书写顺序决定)
4.非静态代码块
[html]  
class Spoon{  
public Spoon(int maker) {  
System.out.println("Spoon("+maker+")");  
}  
static int i;  
static Spoon s = new Spoon(1);  
static{  
System.out.println("static code ");  
i = 47;  
}  
int a;  
//非静态代码块与直接为变量赋值效果相同,只不过可以写更为复杂的代码,非静态代码块一般用于内部类中  
{  
System.out.println("non-static instatnce");  
a = 1;  
}  
}  
public class Test {  
public static void main(String[] args) {  
new Spoon(2);  
new Spoon(3);  
}  
}  
/*  
non-static instatnce  
Spoon(1)  
static code   
non-static instatnce  
Spoon(2)  
non-static instatnce  
Spoon(3)  
*/  
分析:
1.main函数执行new Spoon(2)语句,首先加载Spoon类,先初始化静态变量s,s调用new Spoon(1),此时类Spoon已经加载,所以不用管静态变量和静态代码块了,然后调用非静态代码块和构造函数,输出"non-static code,spoon(1)"。
2.初始化静态代码块,输出"static code"。
3.执行new spoon(2)语句输出“non-static instatnce,Spoon(2)“。
4.执行"new spoon(3)"语句输出”non-static instatnce,Spoon(3)”。
可以尝试调换静态变量s和静态代码块的顺序,发现只是1和2的先后顺序改变而已。
在看下面这个程序
[cpp] 
<span style="font-size:18px">class T{  
public T() {  
System.out.println("T constructor");  
}  
}  
class Spoon{  
public Spoon(int maker) {  
System.out.println("Spoon("+maker+")");  
}  
int a;  
//非静态代码块与直接为变量赋值效果相同,只不过可以写更为复杂的代码,非静态代码块一般用于内部类中  
{  
System.out.println("non-static instatnce");  
a = 1;  
}  
T t1 = new T();  
}  
public class Test {  
public static void main(String[] args) {  
new Spoon(2);  
}  
}  
/* 
non-static instatnce 
T constructor 
Spoon(2) 
*/  
</span>  
通过这个程序,可以发现非静态变量和非静态代码块顺序由书写顺序决定。
5.总结:
以Dog类为例
1.当第一次执行到需要使用Dog类时(如Dog d = new Dog),java首先通过寻找classpath来找到Dog.class,进行加载.
2.初始化Dog类的静态变量和静态代码块(按书写顺序,若静态变量或代码块中还有new Dog,此时不用再管静态变   量和代码块了,如第五个程序中的"static Spoon s = new Spoon(1)")。
3.系统给类分配足够大的内存空间,初始化非静态变量和非静态代码块(顺序由书写顺序决定)
4.最后执行Dog类的构造函数。
5.以后如果还要new Dog类对象时(不是第一次使用了),重复3和4的步骤,不会再去初始化静态变量和静态代码     块了。
大家可以自己写程序实验一下。
6.子类继承父类时的初始化顺序
1.系统启动时,首先初始化父类和子类的static变量和块
2.初始化父类的普通变量,调用父类的构造函数
3.初始化子类的普通变量,调用子类的构造函数

java中普通变量、静态变量、静态代码块初始化的顺序辨析相关推荐

  1. java中你知道这四种代码块吗?

    大家好,我是雄雄,今天给大家分享的是:java中构造代码块的用法. 什么叫代码块?代码块将多行代码封装到一个{}中,形成一个独立的代码区,这就够成了代码块,一般常见的代码块是这样的: Java中,代码 ...

  2. Java中异常处理之try和catch代码块的使用

    转自:https://www.jb51.net/article/72901.htm Java try和catch的使用 尽管由Java运行时系统提供的默认异常处理程序对于调试是很有用的,但通常你希望自 ...

  3. Java(静态)变量和(静态)代码块的执行顺序

    为什么80%的码农都做不了架构师?>>>    本文讨论Java中(静态)变量.(静态)代码块的执行顺序 首先创建3个类: //1.Foo类,用于打印变量 public class ...

  4. java静态变量、静态方法、代码块、main方法

    文章目录 一.类变量 / 静态变量(static) 二.类方法 / 静态方法(static) 三.main方法 四.代码块 (一)static代码块 (二)普通代码块 五.属性初始化.代码块.构造器的 ...

  5. java构造方法,构造代码块,静态代码块的执行顺序

    构造方法,构造代码块,静态代码块的执行顺序 静态代码块:用static声明,jvm加载类时执行,仅执行一次 类中直接用{}定义,每次创建对象时执行 同级别的变量(static和普通变量)的执行顺序由代 ...

  6. java中的starts_Java Math类静态double nextAfter(double starts,double direction)示例

    java中的starts 数学类静态double nextAfter(双向启动,双向) (Math Class static double nextAfter(double starts , doub ...

  7. java中局部变量和成员变量

    java中局部变量和成员变量 1. 定义的位置不一样 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中 2. 作业范围不一样 局部变量:只有方法当中才能使用,出了方法就不能再用 成员变量 ...

  8. java什么是局部变量_java局部变量是什么意思?Java中局部变量与成员变量有哪些区别?...

    大家知道Java中的局部变量吗?今天我们要了解的Java的局部变量及它和成员变量的区别,一起来看看吧. 什么是局部变量? 局部变量时就是只有一部分可见的变量,例如定义在方法中的变量,只有这百个方法才能 ...

  9. 代码块:在Java中,使用{}括起来的代码被称为代码块。

    /*代码块:在Java中,使用{}括起来的代码被称为代码块.根据其位置和声明的不同,可以分为局部代码块:局部位置,用于限定变量的生命周期.构造代码块:在类中的成员位置,用{}括起来的代码.每次调用构造 ...

  10. Java笔记——Java代码块的执行顺序

    Java代码块的执行顺序 Java程序中代码块的执行顺序对于学习Java的人来说是必不可少需要掌握的. 代码块 在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为: 局 ...

最新文章

  1. Django框架(十)--常用字段、参数、元信息、多对多关联关系
  2. 条件随机场CRF HMM,MEMM的区别
  3. 1.15 Python基础知识 - 函数
  4. shell菜鸟学习之echo命令
  5. html z-dext优先级顺序,$ext{1D/1D}$ 动态规划的三种优化
  6. 「译」MotionLayout 介绍 (part II)
  7. C4D插件X-Particles粒子特效(四)
  8. 基于 YOLOV5 的 SAR 图像舰船检测
  9. unity 导出 stl
  10. 二本计算机软件工程专业大学排名,哪些二本大学的软件工程专业最好
  11. 计算机打印机出现副本1,打印机提示Administrator的1个文档被挂起
  12. 淘宝产品,为什么转化率还是这么低?
  13. 传感器怎么获取障碍物的宽度信息_基于多传感器信息融合的机器人障碍物检测...
  14. 计算机网络:自顶向下方法 笔记
  15. 安卓 Charles证书的安装
  16. 小博老师解析经典Java面试题-redirect和forward的区别
  17. 数据库安全小白紧急求助论坛大神,困扰许久
  18. 包含高知漫画家珍贵作品的艺术项目“NAKED Manga Mappin’!”3月6日(周五)起在高知龙马机场展出
  19. Head First JAVA 拾忆-1
  20. Verilog数字系统教程学习——Verilog语法的基本概念

热门文章

  1. npm安装vue-cli时速度慢,fetchMetadata经常卡住并报异常
  2. Nginx资源合并优化模块nginx-http-concat
  3. java课程设计---彩票销售管理系统
  4. C#中string[]数组和liststring泛型的相互转换 【转】
  5. MVVM设计模式《网摘》
  6. 物流管理系统【前台+后台】(Spring+SpringMVC+MyBatis+vue+shiro)(二)
  7. 简单使用Idea创建三层架构项目和数据库连接(使用原生ajax进行访问+ajax)
  8. mysql 利用延迟关联优化查询(select * from your_table order by id desc limit 2000000,20)
  9. eclipse导入Javaweb文件出错解决
  10. 区分Collection、Collector和collect Collectors类的静态工厂方法