Java类的初始化、变量的初始化
来源:互联网 发布:linux的dd创建多个文件 编辑:程序博客网 时间:2024/05/18 00:38
本文简单演示Java类的初始化、变量的初始化顺序,扎实Java 基础,编写高效的code哦
知识点
- Java常量,final 修饰,值被设定后不能再被修改
- 静态变量里,static 修饰,顾名思义,无须创建对象,便可在内存中申请一个存储空间进行存储
- 成员变量,也称实例变量,它随着当前对象的建立而建立,随着对象的销毁而销毁,存在于对象所在的堆内存中
- 构造器,创建class对象时执行
- 静态初始化块,执行优先级高于非静态的初始化块,它会在对象装载到 jvm的时候执行一次,执行完成便销毁,只能初始化 static 修饰的变量
- 非静态初始化块,执行的时候如果有静态初始化块,先执行静态初始化块再执行非静态初始化块,在每个对象生成时都会被执行一次,它可以初始化类的实例变量。但它会在构造函数执行之前被执行。
类的初始化顺序
Java中类初始化顺序,依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。。
实例代码
父类 Human
package com.lazy.pojos;import com.lazy.interfaces.IBehaviour;/** * Created by system on 16/9/10. */public class Human /*extends Object*/ implements IBehaviour { //default super class Object String TAG = "Human"; public static String sTAG = "static Human"; protected long identifier = System.currentTimeMillis();//身份标识 protected int age; protected int height; protected String name; /* 静态初始化块 */ static { System.out.println("Human" + " 静态初始化块"); } /* 初始化块 (实例初始化器)*/ { System.out.println(TAG + " 初始化块"); System.out.println(TAG + " " + identifier); } public Human() { System.out.println(TAG + " 构造器"); } @Override public void eat() { }}
子类Woman
package com.lazy.pojos;/** * Created by system on 16/9/10. */public class Woman extends Human {}
子类Man
package com.lazy.pojos;/** * Created by system on 16/9/10. */public class Man extends Human { /* 静态变量 */ public static String staticVar = "staticVar"; /* 成员变量 */ public String field = "field"; String TAG = "Man"; /* 静态初始化块 */ static { System.out.println("Man 静态初始化块"); System.out.println("Man staticVar =" + staticVar); } /* 初始化块 (类实例初始化器)*/ { System.out.println(TAG + " 初始化块"); System.out.println(TAG + " field = " + field); } /* 构造器 */ public Man() {// super(); //隐式 System.out.println(TAG + " 构造器"); }}
测试类:FinalVarTest
public class InitializeOrderTest { public static void main(String[] args) { new Man(); new Woman(); }}
执行结果:如图
Java 类的初始化,可以分为单一对象的初始化,已经有继承关系的对象初始化,然而java 所有类的基类都是Object。有基类的先初始化基类,再初始化自身。Woman 类之所以能调用基类构造器,皆因为Java 编译器,class 文件中生成了一个默认构造器。如下图
IntelliJ IDEA 能直接查看class 文件,而且调试功能更为强大
变量初始化顺序
实例代码
package com.lazy.pojos;public class FinalVar { String mg = "msg"; static String msg = "static msg"; final static String msg2 = "final static msg"; public static final String MSG = "MSG"; public static final String MSG2 = "MSG" + 2; //MSG2 = "MSG2" public static final String MSG3 = "MSG" + "3"; // MSG3 = "MSG3" public static final String MSG4 = msg + "4"; //MSG4; 只 declare no value public static final String MSG5 = msg2 + "5"; //MSG5 = "final static msg5"; public static String MSG6 = msg2 + "6"; //MSG6; 只 declare no value public final String MSG7 = msg2 + "7"; ///MSG7 = "final static msg7"; public final String MSG8 = mg + "8"; //MSG8; 只 declare no value public static final int NUM = 100 * 10; //NUM =1000; public int num = 100 * 10; //NUM; 只 declare no value final String MG = "MG"; static { System.out.println("static"); }}
对于变量我们如何测试变量的初始化顺序呢
- 查看Class 反编译后的代码
- Debug 变量
class 文件
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package com.lazy.pojos;public class FinalVar { String mg = "msg"; static String msg = "static msg"; static final String msg2 = "final static msg"; public static final String MSG = "MSG"; public static final String MSG2 = "MSG2"; public static final String MSG3 = "MSG3"; public static final String MSG4; public static final String MSG5 = "final static msg5"; public static String MSG6; public final String MSG7 = "final static msg7"; public final String MSG8; public static final int NUM = 1000; public int num; final String MG; public FinalVar() { this.MSG8 = this.mg + "8"; this.num = 1000; this.MG = "MG"; } static { MSG4 = msg + "4"; MSG6 = "final static msg6"; System.out.println("static"); }}
测试代码
public class FinalVarTest { public static void main(String[] args) { System.out.println(FinalVar.MSG);// System.out.println(FinalVar.MSG4);// new FinalVar(); }}
由此可得:
1.static final 变量在编译时,编译器已经为之初始化值,static 变量要比成员变量优先初始化,仅初始化一次。——若代码中引用到 一个 static 变量,便会初始化整个类的static 变量,static final 变量则不会。
看代码
①如 static final 变量 MSG2 , 编译器自动为它 拼接成:MSG2。②再看 MSG4 ,它由 static 变量 msg + “4” ,msg 值不是final ,常量值,编译器只好先declare MSG4 这个变量,在 static 代码块中进行赋值; ③而 MSG5 变量的默认值为 “final static msg5”,④即 static final 变量在赋值时,值必须编译前就明确了. 若采用 static 变量进行赋值,—— 只能static 代码块中进行赋值。2.对于 成员变量 MSG8 ,以下的声明的成员变量 如 num 打开class 文件看到都只在class 构造器中被赋值,经我测试只有成员变量赋值时引用了其它变量时,都会在构造器中被赋值。
如果你还不明白变量初始化顺序,可以在变量上打变量断点
debug运行代码便会挂起
最后
对于 变量的初始化来说,情况比较多,还得多实践。如果想了解jvm 类加载的请阅读 [ JVM 类加载的那些事 ]
对于本文的字符串拼接其细节的请参考 [ 浅谈Java String内幕 ], [ 什么是字符串常量池? ] 两篇文章。
- Java类的初始化、变量的初始化
- Java类变量的初始化
- JAVA变量的初始化
- Java变量的初始化
- java变量的初始化
- [java]变量的初始化
- Java变量的初始化
- Java类的初始化顺序 (静态变量、静态初始化块、变量、初始化块、构造方法)
- Java类的初始化顺序 (静态变量、静态初始化块、变量、初始化块、构造器
- Java类的初始化顺序 (静态变量、静态初始化块、变量、初始化块、构造器)
- 变量的初始化、类的初始化
- Java类成员变量的初始化顺序
- java类成员变量的初始化顺序
- Java类成员变量的初始化顺序
- Java类的变量初始化顺序
- java类中变量的初始化
- Java类变量的初始化时机
- [ java ] 变量的初始化问题!
- 欧拉回路
- 控制台输入日期格式存储到数据库
- 关于css浮动的一些理解
- Strtus2的基本使用
- Shell注释
- Java类的初始化、变量的初始化
- Hive永久函数
- 轻松入门React和Webpack
- 第五周项目4-长方柱类
- 安装git服务器
- 机器学习资源
- Java中List的remove方法
- 交集问题
- kali-linux安装VirtualBox