转:

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. QT学习之路DAY1之初学QT的小项目

    以下所有代码均利用软件QT5编写 项目一:Hello world! 利用QTcreator创建项目 修改main.cpp代码为 #include "mainwindow.h" #i ...

  2. C# Winform 禁止一个进程运行多次

    禁止一个进程运行多次 using System; using System.Windows.Forms; namespace StartExe { static class Program { /// ...

  3. Centos使用光盘yum源

    yum查看所有源 yum repolist all 方法一:本机使用光盘源安装软件的设置 mkdir /media/cdrom mount /dev/cdrom  /media/cdrom vim / ...

  4. How to export Overload functions from DLL?

    Library that exports functions library liba; procedure F(X: Integer); stdcall; overload; begin end; ...

  5. mailx使用465端口发邮件

    centos上mailx通过465端口发送邮件   最近在看zabbix发送邮件的时候,发现自己的邮件总是无法发送,这里可能是外网防火墙禁止25端口,那么如何绕过25端口呢?  我使用的是163邮箱的 ...

  6. Python 列出 windows 安装的软件

    Python 列出 windows 安装的软件 参考链接:https://stackoverflow.com/questions/802499/how-can-i-enumerate-list-all ...

  7. MyBatis-10-多对一处理

    10.多对一处理 多对一: 多个学生,对应一个老师 对于学生这边而言,关联...多个学生,关联一个老师[多对一] 对于老师而言,集合,一个老师又很多学生[一对多] SQL: CREATE TABLE ...

  8. HTML中dl元素的高度问题

    dl元素通常用来创建一个描述列表,但是在我使用的过程中发现了一个小问题. 定义及用法 在MDN中 <dl> 元素的定义是:一个包含术语定义以及描述的列表,通常用于展示词汇表或者元数据 (键 ...

  9. C# 截取屏幕方法

    this.Visible = false; System.Threading.Thread.Sleep(); Bitmap bit = new Bitmap(Screen.PrimaryScreen. ...

  10. 题解 [BZOJ1295][SCOI2009] 最长距离

    题面 解析 \(n\)只有\(30\)可以直接枚举每个矩形, 判断他们的左上角到右下角或右上角到左上角的最短路是否小于\(T\). 最短路可以用\(dijkstra\). 一开始想用\(DP\)写最短 ...