Java中非静态成员变量、静态成员变量的初始化时机
转:
Java中非静态成员变量、静态成员变量的初始化时机。
Java中非静态成员变量、静态成员变量的初始化时机。
非静态变量
我们在这里分析三种结构,着重分析这三种结构的初始化顺序:
- 成员变量初始化语句;
- 成员变量初始化块;
- 构造函数;
示例一:
public class MyTest {
private String name = "wei.hu";
public MyTest(String name) {
System.out.println("This is constructor. Will assign the variable name to: " + name + ".");
System.out.println("Before the name was modified: " + this.name);
this.name = name;
System.out.println("After the name was modified: " + this.name);
}
{
System.out.println("This is initialize block. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + this.name);
this.name = "chouchou";
System.out.println("After the name was modified: " + this.name);
}
public String getName() {
return name;
}
public static void main(String[] args) {
MyTest myTest = new MyTest("mengna");
System.out.println(myTest.getName());
}
}
#输出
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: wei.hu
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: chouchou
After the name was modified: mengna
mengna
示例二:
public class MyTest {
public MyTest(String name) {
System.out.println("This is constructor. Will assign the variable name to: " + name + ".");
System.out.println("Before the name was modified: " + this.name);
this.name = name;
System.out.println("After the name was modified: " + this.name);
}
private String name = "wei.hu";
{
System.out.println("This is initialize block. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + this.name);
this.name = "chouchou";
System.out.println("After the name was modified: " + this.name);
}
public String getName() {
return name;
}
public static void main(String[] args) {
MyTest myTest = new MyTest("mengna");
System.out.println(myTest.getName());
}
}
#结果(与示例一相同)
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: wei.hu
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: chouchou
After the name was modified: mengna
mengna
示例三:
public class MyTest {
public MyTest(String name) {
System.out.println("This is constructor. Will assign the variable name to: " + name + ".");
System.out.println("Before the name was modified: " + this.name);
this.name = name;
System.out.println("After the name was modified: " + this.name);
}
{
System.out.println("This is initialize block. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + this.name);
this.name = "chouchou";
System.out.println("After the name was modified: " + this.name);
}
private String name = "wei.hu";
public String getName() {
return name;
}
public static void main(String[] args) {
MyTest myTest = new MyTest("mengna");
System.out.println(myTest.getName());
}
}
#结果
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: null
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: wei.hu
After the name was modified: mengna
mengna
分析:
注意本示例的结果与上面两个示例的结果不同。
1、当我们想将成员变量name赋值为chouchou之前,发现this.name为null。也就是说初始化语句没有先执行,而是先执行了初始化块;
2、当在执行构造函数时,我们想将成员变量name赋值为mengna,发现赋值之前,this.name不再是chouchou,而是wei.hu,这说明了什么?
因为初始化块先执行,如果紧接着执行构造函数的话,那么在构造函数赋值语句执行之前,this.name应该是chouchou才对。但是在构造函数赋值语句执行之前,this.name的值变成了wei.hu,那么足以证明:
1)初始化块先执行;
2)下来执行了初始化语句;
3)最后执行了构造函数;
结论:
通过上面三个示例,我们可以发现,对于非静态的成员变量:
- 初始化语句、初始化块,总是先于构造函数执行;
- 初始化语句、初始化块的和执行顺序,取决于 初始化语句、初始化块在代码中的书写顺序。写在上面的先执行。
静态变量
我们在这里也分析三种结构:
- 静态初始化语句;
- 静态初始化块;
- 构造函数;
示例一:
public class MyTest {
public static String name = "wei.hu";
public MyTest() {
System.out.println("This is constructor. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + name);
name = "chouchou";
System.out.println("After the name was modified: " + name);
}
static {
System.out.println("This is static initialize block. Will assign the variable name to: mengna");
System.out.println("Before the name was modified: " + name);
name = "mengna";
System.out.println("After the name was modified: " + name);
}
public static void main(String[] args) {
System.out.println(MyTest.name);
}
}
#结果
This is static initialize block. Will assign the variable name to: mengna
Before the name was modified: wei.hu
After the name was modified: mengna
mengna
分析:
通过打印输出,我们发现在执行静态初始快之前,静态变量name已经初始化为wei.hu了。也就是说:
1、静态初始化语句先执行;
2、下来执行静态初始化块;
3、构造函数未执行;
---------------------
示例二:
public class MyTest {
public MyTest() {
System.out.println("This is constructor. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + MyTest.name);
name = "chouchou";
System.out.println("After the name was modified: " + MyTest.name);
}
static {
System.out.println("This is static initialize block. Will assign the variable name to: mengna");
System.out.println("Before the name was modified: " + MyTest.name);
name = "mengna";
System.out.println("After the name was modified: " + MyTest.name);
}
public static String name = "wei.hu";
public static void main(String[] args) {
System.out.println(MyTest.name);
}
}
#结果
This is static initialize block. Will assign the variable name to: mengna
Before the name was modified: null
After the name was modified: mengna
wei.hu
分析:
初始化块在对静态变量赋值之前,发现MyTest.name的值为空。 在最后打印出MyTest.name时,发现输出的值是wei.hu,而不是mengna。也就是说,在初始化块执行之后,执行了静态初始化语句。
1、先执行静态初始化块;
2、再执行静态初始化语句;
3、构造函数未执行;
---------------------
结论:
对于静态字段,初始化有如下规则:
1. 若静态初始化语句在前,静态代码块在后,则先执行静态初始化语句;
2. 若静态代码块在前,静态初始化语句在后,则先执行静态代码块;
Java中非静态成员变量、静态成员变量的初始化时机的更多相关文章
- java 静态代码块 代码块 构造函数 静态成员变量 成员变量的初始化顺序
没有父类的情况 1,静态代码块-->静态成员变量-->成员变量(实例属性)-->代码块-->构造函数 2, 静态代码块 和 静态成员变量 只会初始化一次 有父类的情况 1,父类 ...
- Java学习笔记11---静态成员变量、静态代码块、成员变量及构造方法的初始化或调用顺序
当创建一个对象时,各种成员变量及构造方法的初始化或调用顺序是怎样的呢? (1).如果类尚未加载,则先初始化静态成员变量和静态代码块,再初始化成员变量,最后调用相应的构造方法: (2).如果类已经加载过 ...
- C#中静态成员和实例变量
昨天晚上看静态成员和实例变量的时候,看到这样的一句话:默认情况下,若成员被定义为实例变量,这就意味着类需要为每个实例都建立一个副本,而在定义一个静态变量的时候,只存在此成员的一个副本. 呵呵,今天跟前 ...
- JAVA当中变量什么时候需要初始化
1. 对于类的成员变量,不管程序有没有显式的进行初始化,Java虚拟机都会先自动给它初始化为默认值. 默认值如下: Boolean false ...
- [20160731][转]JAVA当中变量什么时候需要初始化
1. 对于类的成员变量,不管程序有没有显式的进行初始化,Java虚拟机都会先自动给它初始化为默认值. 默认值如下: Boolean false ...
- java中static变量的声明和初始化
目录(?)[+] 问题1静态变量如何初始化 问题2JDK如何处理static块 问题3如何看待静态变量的声明 对初始问题的解答 在网上看到了下面的一段代码: public class Test ...
- Java 变量的声明及初始化
格式: 数据类型 变量名字1 , 变量名字2 ,--变量名字n ; 案例: int i 声明了一个整形的变量. double d 声明了一个double数据类型的变量 float f 声明了一个fl ...
- java入门---变量类型&类变量&局部变量&实例变量&静态变量
在Java语言中,所有的变量在使用前必须声明.声明变量的基本格式如下: type identifier [ = value][, identifier [= value] ...] ; ...
- 理解Java中的对象,变量和方法
1.对象的创建和销毁 1.1 对象的创建 这里只介绍创建对象与构造方法的关系 (1).每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程,准确的说,在Java语言中使用new操 ...
随机推荐
- thymeleaf的内联th:inline(在javascript访问model中的数据)
thymeleaf模板引擎为前端数据的获取提供了较大的便利,在html标签内可通过th标签加${}表达式访问model里的对象数据.但如果不想通过th标签而是简单地访问model对象数据,或是想在ja ...
- TF_Variable Sharing
Reference: http://jermmy.xyz/2017/08/25/2017-8-25-learn-tensorflow-shared-variables/ Tensorflow does ...
- java线程基础巩固---ThreadGroup API学习
ThreadGroup初识: 这次来学习一个新的线程概念---线程组(ThreadGroup),首先从JDK文档中对它进行一个大致的了解,如下: 下面开始用代码来进行说明,对于一个线程来说如果没有指定 ...
- Python&Selenium 数据驱动【unittest+ddt+xml】
一.摘要 本博文将介绍Python和Selenium做自动化测试的时候,基于unittest框架,借助ddt模块使用xml文件作为数据文件作为测试输入 二.xml文件 <?xml version ...
- go语言日期时间格式化
原文: http://www.golangprograms.com/get-current-date-and-time-in-various-format-in-golang.html package ...
- python+Appium自动化:H5元素定位
问题思考 在混合开发的App中,经常会有内嵌的H5页面.那么这些H5页面元素该如何进行定位操作呢? 解决思路 针对这种场景直接使用前面所讲的方法来进行定位是行不通的,因为前面的都是基于Andriod原 ...
- localstorage ie11不支持
据我所知,localstorage在高版本的ie.谷歌.火狐下都是支持的,以前没在ie上看过,不清楚,今天我用ie11打开我vue编译后的html,竟然发现不支持localstorage了,用仿真的i ...
- 关于topN问题的几种解决方案
在系统中,我们经常会遇到这样的需求:将大量(比如几十万.甚至上百万)的对象进行排序,然后只需要取出最Top的前N名作为排行榜的数据,这即是一个TopN算法.常见的解决方案有三种: (1)直接使用Lis ...
- @Import注解的作用
在@Import注解的参数中可以填写类名,例如@Import(Abc.class),根据类Abc的不同类型,spring容器有以下四种处理方式: 1. 如果Abc类实现了ImportSelector接 ...
- MFC 模态对话框、非模态对话框
modal dialogs与modeless dialogs,modal dialogs会让原窗体不被选中,modeless dialogs原窗体依然可以选中. 1.模态对话框的显示 DlgModal ...