转:

Java中非静态成员变量、静态成员变量的初始化时机。

2018年05月22日 11:48:11 SilenceCarrot 阅读数 421
 
版权声明:技术就要分享才有意思,欢迎大家分享(注明出处),欢迎大家纠错。 https://blog.csdn.net/SilenceCarrot/article/details/80403635

Java中非静态成员变量、静态成员变量的初始化时机。

非静态变量

我们在这里分析三种结构,着重分析这三种结构的初始化顺序:

  1. 成员变量初始化语句;
  2. 成员变量初始化块;
  3. 构造函数;

示例一:

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)最后执行了构造函数;

结论:
通过上面三个示例,我们可以发现,对于非静态的成员变量:

  1. 初始化语句、初始化块,总是先于构造函数执行;
  2. 初始化语句、初始化块的和执行顺序,取决于 初始化语句、初始化块在代码中的书写顺序。写在上面的先执行。

静态变量

我们在这里也分析三种结构:

  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中非静态成员变量、静态成员变量的初始化时机的更多相关文章

  1. java 静态代码块 代码块 构造函数 静态成员变量 成员变量的初始化顺序

    没有父类的情况 1,静态代码块-->静态成员变量-->成员变量(实例属性)-->代码块-->构造函数 2, 静态代码块 和 静态成员变量 只会初始化一次 有父类的情况 1,父类 ...

  2. Java学习笔记11---静态成员变量、静态代码块、成员变量及构造方法的初始化或调用顺序

    当创建一个对象时,各种成员变量及构造方法的初始化或调用顺序是怎样的呢? (1).如果类尚未加载,则先初始化静态成员变量和静态代码块,再初始化成员变量,最后调用相应的构造方法: (2).如果类已经加载过 ...

  3. C#中静态成员和实例变量

    昨天晚上看静态成员和实例变量的时候,看到这样的一句话:默认情况下,若成员被定义为实例变量,这就意味着类需要为每个实例都建立一个副本,而在定义一个静态变量的时候,只存在此成员的一个副本. 呵呵,今天跟前 ...

  4. JAVA当中变量什么时候需要初始化

    1. 对于类的成员变量,不管程序有没有显式的进行初始化,Java虚拟机都会先自动给它初始化为默认值. 默认值如下:             Boolean      false             ...

  5. [20160731][转]JAVA当中变量什么时候需要初始化

    1. 对于类的成员变量,不管程序有没有显式的进行初始化,Java虚拟机都会先自动给它初始化为默认值. 默认值如下:             Boolean      false             ...

  6. java中static变量的声明和初始化

     目录(?)[+] 问题1静态变量如何初始化 问题2JDK如何处理static块 问题3如何看待静态变量的声明 对初始问题的解答 在网上看到了下面的一段代码: public class Test  ...

  7. Java 变量的声明及初始化

    格式: 数据类型 变量名字1 , 变量名字2 ,--变量名字n ; 案例: int i 声明了一个整形的变量. double d 声明了一个double数据类型的变量 float  f 声明了一个fl ...

  8. java入门---变量类型&类变量&局部变量&实例变量&静态变量

        在Java语言中,所有的变量在使用前必须声明.声明变量的基本格式如下:     type identifier [ = value][, identifier [= value] ...] ; ...

  9. 理解Java中的对象,变量和方法

    1.对象的创建和销毁 1.1 对象的创建 这里只介绍创建对象与构造方法的关系 (1).每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程,准确的说,在Java语言中使用new操 ...

随机推荐

  1. (十一)tina | openwrt关闭调试串口(DEBUG UART)

    //编辑以下文件 vi target/allwinner/astar-parrot/base-files/etc/inittab  //不同系统文件路径注意更改 //文件内容如下,注释::askcon ...

  2. 关于Linux连接工具mobaxterm显示中文乱码问题

    本人用的是MobaXterm Personal 9.1版本.近期发现连接上服务器,查看日志时,发现中文乱码,无法正常显示.甚是苦恼.百度搜索该工具显示乱码问题,无一人解决.提倡更换连接工具.无意间发现 ...

  3. 0912 for循环及内置方法

    目录 for 循环 1.循环 2.循环取值 3.range 4.for + break 5.for+continue 6.for + else 数字类型内置方法 整型 浮点型 字符串 1.作用 2.作 ...

  4. node监听80端口权限问题

    报了这个错误: Error: listen EACCES: permission denied 127.0.0.1:80 at Server.setupListenHandle [as _listen ...

  5. zabbix内存溢出解决方法

    1406:20180802:183248.783 __mem_malloc: skipped 0 asked 48 skip_min 4294967295 skip_max 0 1406:201808 ...

  6. 【线段树 dp】8.6集合

    线段树维护dp 题目大意 给定初始大小为 $N$ 的正整数集合.定义两个数$x$和$y$建立联系的的代价为 $|x-y|$.我们定义整数集合的代价为:将每个整数都与至少一个另外的整数建立联系之后,所有 ...

  7. 详解Object.create(null)

    在Vue和Vuex的源码中,作者都使用了Object.create(null)来初始化一个新对象.为什么不用更简洁的{}呢? 在SegmentFault和Stack Overflow等开发者社区中也有 ...

  8. Codeforces Round #589 (Div. 2) B. Filling the Grid

    链接: https://codeforces.com/contest/1228/problem/B 题意: Suppose there is a h×w grid consisting of empt ...

  9. jQuery系列(十二):事件委托

    1.什么是事件委托 通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这 ...

  10. NotFoundError (see above for traceback): Key local3/weights not found in checkpoint

    解决办法 原文 https://www.jianshu.com/p/2de8e01af88d with tf.Session() as sess: tf.get_variable_scope().re ...