转:

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. 实时跟踪之TRACA

    背景: 目前,在实时跟踪领域存在着越来越多的先进方法,同时也极大地促进了该领域的发展.主要有两种不同的基于深度学习的跟踪方法:1.由在线跟踪器组成,这些跟踪器依赖网络连续的微调来学习目标的变化外观,精 ...

  2. 13_Redis_持久化

    一:概述: Redis的高性能是山于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化. Redis支持两种方式的持久化,一 ...

  3. PAT Basic 1085 PAT单位排行 (25 分)

    每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜.本题就请你实现这个功能. 输入格式: 输入第一行给出一个正整数 N(≤),即考生人数.随后 N 行,每行按下列格式给出一个考生的信息: 准 ...

  4. okhttp拦截器之RetryAndFollowUpInterceptor&BridgeInterceptor分析

    在上一次[https://www.cnblogs.com/webor2006/p/9096412.html]对okhttp的拦截器有了一个初步的认识,接下来则对具体的拦截器一个个进行了解. Retry ...

  5. 《黑白团团队》第九次团队作业:Beta冲刺第三天

    项目 内容 作业课程地址 任课教师首页链接 作业要求 团队项目 填写团队名称 黑白团团队 填写具体目标 认真负责,完成项目 团队项目Github仓库地址链接. 第一天 日期:2019/6/24 1.1 ...

  6. Java 实现大文件切割并生成多个文件

    话不多说,直接上代码 import java.io.*; /*** * 分割大文件 * ( * SQL 文件太大(insert),第三方工具无法一次性读取,进行分割 * 生成 一个一个文件 * ) * ...

  7. 如何低成本搭建dnslog服务器

    DNSLog,简单来说,就是通过记录对于域名的DNS请求,通过dns请求这个相对"隐蔽"的渠道,来委婉地获取到想要获得的信息. 例如,在一个针对mysql数据库的注入中,如果没有回 ...

  8. Qt5 使用lambda

    c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11 m_timer = new QTimer(); m_timer->start() ...

  9. HZOJ 20190818 NOIP模拟24题解

    T1 字符串: 裸的卡特兰数题,考拉学长讲过的原题,就是bzoj3907网格那题,而且这题更简单,连高精都不用 结论$C_{n+m}^{n}-C_{n+m}^{n+1}$ 考场上10min切掉 #in ...

  10. C# 父类代码动态转换子类

    百度上搜索C# 如何父类运行时转换成子类,没有得到相应答案,突然想起C# 有dynamic类型试试看结果成功了... 以后编写代码类似这样的代码 就可以删减掉了 if (en.type == EMap ...