转:

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. PXC集群信息查询

    目录 PXC集群信息查询 pxc流量控制 PXC节点状态 PXC集群状态 节点与集群的相关信息 PXC集群事务相关信息 PXC集群信息查询 show status like "%wsrep% ...

  2. mysql 5.6.38 数据库编译安装

    一.系统环境: # cat /etc/redhat-release CentOS release 6.9 (Final) 二.mysql 编译安装: 1.安装依赖包: yum install -y n ...

  3. 5. First-Class Functions

    Function in python are first-class objects (runtime / element / argument / return) 1. Treating a Fun ...

  4. Java重写(Override)与重载(Overload)

    方法的重写规则 参数列表必须完全与被重写方法的相同: 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同): ...

  5. spring 的自动定时任务

    spring的自动定时任务有两种 第一种:通过xml配置来设置 需要在xml中引入新的约束,并且需要配置<task:scheduled-tasks> ,主要配置内容如下: <?xml ...

  6. HTML5——2 HTML5视频

    在以往我们还是使用flash来进行播放视频,但是它有先天的缺陷,比如,很多的浏览器并不会直接去支持flash插件,需要你自己去安装,而且版本也很难去统一,也有浏览器先天集成了这个插件,比如Chrome ...

  7. java递归方法查找某目录下包含有某字符串的文件

    最近在安装mysql5.6的时候,因为是免安装版的所以有些配置项需要手动配置.但是配置某一项的时候(例如:max_allowed_packet=xxxxx),不知道max_allowed_packet ...

  8. 牛客练习赛3 绝对半径 ——k尺取法

    题目 链接 题意:一个n个数字的序列,最多去掉其中k个,使得连续相同数字序列的长度尽量长 分析 如果不考虑去掉元素,就是普通的尺取.考虑到去元素,则只需做一点修改. 先离散化,再把每种元素的位置用va ...

  9. @Configuration的使用 和作用(转)

    从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplic ...

  10. Break 和 Continue 语句

    break 语句用于跳出循环. continue 用于跳过循环中的一个迭代. 1.break关键字可以用来退出switch或循环语句   不能在IF语句中使用break和continue 示例:在if ...