一、变量与构造器的初始化顺序

我们知道一个类中具有类变量、类方法和构造器(方法中的局部变量不讨论,他们是在方法调用时才被初始化),当我们初始化创建一个类对象时,其初始化的顺序为:先初始化类变量,再执行构造器方法。代码验证:

public class Demo01 {
public int a1 = 1;
public String a2 = "initiaied!"; public Demo01() {
System.out.println(a1);
System.out.println(a2);
System.out.println("构造器方法被执行");
} public static void main(String[] args) {
Demo01 demo01 = new Demo01();
}
} 运行结果:
1
initiaied!
构造器方法被执行

可以看出,当我们创建一个Demo01对象时,先初始化了变量a1和a2,然后执行构造器方法。

二、静态变量与非静态变量的初始化顺序

静态变量是属于类本身,无论创建多少个对象,静态变量都只有一份存储区域,因此他会在类首次被访问或者首次创建类对象时被初始化,而且有且只能初始化一次。而非静态变量是属于每个对象,他是在创建每个对象时都初始化一次。因此,静态变量要先于非静态进行初始化。例子:

public class Demo02 {
public Cup cup1 = new Cup(1);
public static Cup cup2 = new Cup(2); public Demo02() {
System.out.println("Demo02构造器被执行!");
} public static void main(String[] args) {
Demo02 demo02 = new Demo02();
Demo02 demo02_01 = new Demo02();
}
} class Cup {
public Cup(int i) {
System.out.println("Cup->" + i);
}
} 运行结果:
Cup->2
Cup->1
Demo02构造器被执行!
Cup->1
Demo02构造器被执行

当程序要执行main方法时,会先加载Demo02类文件,在加载时就会先初始化静态变量cup2,因此控制台输出"cup->2"。类加载完后,开始执行main方法,创建demo02对象,这时就会初始化类中的非静态变量cup1,控制台输出"cup->1",然后执行构造器方法。创建第二个对象时,只初始化cup1,cup2为静态变量只初始化一次。

三、静态代码块与非静态代码块

静态代码块本质上就是一段静态变量的代码,其初始化和静态变量没有区别:当类首次被访问或者首次创建该类对象时被初始化,并且只初始化一次。

非静态代码块就是一段非静态变量的代码,他和非静态变量的初始化没有区别。

public class Demo03 {
static Table table1;
Table table2; static {
table1 = new Table(1);
} {
table2 = new Table(2);
} public Demo03() {
System.out.println("Demo03构造器被执行");
} public static void main(String[] args) {
new Demo03();
}
} class Table {
public Table(int i) {
System.out.println("Table->" + i);
}
} 运行结果:
Table->1
Table->2
Demo03构造器被执行

四、父类与子类的初始化顺序

没有父类就没有子类,因此无论是类加载还是创建实例对象,父类都优先于子类进行初始化。

public class Demo04 extends Insect {
private int k = fun("Demo04中的k被初始化");
private static int x2 = fun("Demo04中的x2被初始化"); public Demo04() {
System.out.println("k=" + k);
System.out.println("j=" + j);
} public static void main(String[] args) {
Demo04 demo04 = new Demo04();
}
} class Insect {
public int i = 9;
public int j;
public static int x1 = fun("Insect中的x1被初始化"); public Insect() {
System.out.println("i=" + i + ",j=" + j);
j = 39;
} public static int fun(String s) {
System.out.println(s);
return 47;
}
}
运行结果:
Insect中的x1被初始化
Demo04中的x2被初始化
i=9,j=0
Demo04中的k被初始化
k=47
j=39

当执行main方法时,加载器开始加载Demo04类文件,在加载过程中,加载器会注意到他有一个父类Insect还没被加载,因此会先加载父类Insect文件。类加载过程中会完成静态变量的初始化(此时并不执行构造器方法,构造器方法只有在创建对象时调用),Insect类加载完成后,接着加载Demo04类,都加载完成后,就开始执行main方法中的代码,创建Demo04对象。

由于继承关系,因此先创建父类Insect的实例对象,因此父类中的变量初始化和构造器先被执行,然后在初始化子类Demo04中的非静态变量和执行构造器方法。

五、总结

最后放一段代码,把前面所说情况都放在一起。

public class Son extends Father {
int m = fun("Son中的m 被初始化"); public Son() {
System.out.println("m = " + m);
System.out.println("j = " + j);
} public static int x3 = fun("Son中的x3 被初始化"); public static void main(String[] args) {
Son son = new Son();
}
} class Father extends GrandFather { public int k = fun("Father中的k被初始化");
public static int x2 = fun("Father中的x2被初始化"); public Father() {
System.out.println("k=" + k);
System.out.println("j=" + j);
}
} class GrandFather {
public int i = 9;
public int j;
public static int x1 = fun("GrandFather中的x1被初始化"); public GrandFather() {
System.out.println("i=" + i + ",j=" + j);
j = 39;
} public static int fun(String s) {
System.out.println(s);
return 47;
}
}
运行结果:
GrandFather中的x1被初始化
Father中的x2被初始化
Son中的x3 被初始化
i=9,j=0
Father中的k被初始化
k=47
j=39
Son中的m 被初始化
m = 47
j = 39

浅谈Java类中的变量初始化顺序的更多相关文章

  1. java类中成员的初始化顺序(一)

    类被创建之后的成员的初始化顺序到底是怎么样的? 首先 不考虑继承 package com; public class DemoOne { /** * 关于类的初始化顺序 */ //不考虑继承结构的情况 ...

  2. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  3. Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序

    先看一道Java面试题: public class Baset { private String baseName = "base"; // 构造方法 public Baset() ...

  4. 浅谈JAVA GUI中,AWT与Swing的区别、联系及优缺点

    浅谈JAVA GUI中,AWT与Swing的区别.联系及优缺点 A.区别 1.发布的时间 AWT是在JDK 1.0版本时提出的 Swing是在AWT之后提出的(JAVA 2) 2. ”重量” AWT是 ...

  5. 【基础】java类的各种成员初始化顺序

    父子类继承时的静态代码块,普通代码块,静态方法,构造方法,等先后顺序 前言: 普通代码块:在方法或语句中出现的{}就称为普通代码块.普通代码块和一般的语句执行顺序由他们在代码中出现的次序决定--“先出 ...

  6. 在java中浅谈Math类中的常用方法

    通过最近的学习,学到了一些的Math类中的常见方法 package org.stm.demo; public class Test { public static void main(String[] ...

  7. 分析java类的静态成员变量初始化先于非静态成员变量

    依上图中当class字节码文件被jvm虚拟机加载到内存中依次经过 连接 验证:对字节码进行验证 准备:给静态变量分配内存并赋予变量类型各自的默认值(注:基本类型为0或false,对象为null,sta ...

  8. 浅谈java类集框架和数据结构(1)

    在另外一篇博客我简单介绍了java类集框架相关代码和理论. 这一篇博客我主要分析一下各个类集框架的原理以及源码分析. 一:先谈谈LinkedList 这是LinkedList源码的开头,我们能看到几点 ...

  9. Java类中代码的执行顺序 静态代码块>构造代码块>构造方法

    一:静态代码块 注意是代码块,不是静态函数.函数要调用才执行,代码块加载就执行,一般是静态变量的声明与初始化.被static修饰的代码块(赋值.输出操作等).类中静态语句块仅在类加载时被执行一次 如 ...

随机推荐

  1. open数据库报错ERROR at line 1: ORA-03113: end-of-file on communication channel Process ID: 3880 Session ID: 125 Serial number: 3

    1.今天打开数据时,失败,报错 ERROR at line 1:ORA-03113: end-of-file on communication channelProcess ID: 3880Sessi ...

  2. 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则

    目录 前言 聚合 聚合和聚合根原则 包含业务原则 单个单元原则 事务边界原则 可序列化原则 聚合和聚合根最佳实践 只通过ID引用其他聚合 用于 EF Core 和 关系型数据库 保持聚合根足够小 聚合 ...

  3. EEPROM工作原理透彻详解

    原文链接点击这里 EEPROM(Electrically Erasable Programmable read only memory)即电可擦可编程只读存储器,是一种掉电后数据不丢失(不挥发)存储芯 ...

  4. Linkerd 2.10(Step by Step)—设置服务配置文件

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 部署 ...

  5. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  6. Jenkins+SonarQube实现C#代码质量检查

    环境准备 SonarQube 项目创建 jenkins Windows构建节点配置 安装与SonarQube服务端相同版本jdk 安装sonar-scanner 并配置环境变量 安装Visual St ...

  7. 计算机、程序和java简介

    内存 计算机的内存是由一个有序的字节序列组成,用于存储程序及程序需要的数据.你可以将内存想象成计算机执行程序的工作区域.一个程序和它的数据在被CPU执行前必须移到计算机的内存中. 每个字节都是有一个唯 ...

  8. SpringBoot拦截器及源码分析

    1.拦截器是什么 java里的拦截器(Interceptor)是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止 ...

  9. JavaScript中使用eval()方法解析json串

    最近在js用到了eval()方法,在这里做个笔记 当时是这么用的:data = eval("("+data+")"); data为后台向前台传送的一个json串 ...

  10. Leetcode No.119 Pascal's Triangle II(c++实现)

    1. 题目 1.1 英文题目 Given an integer rowIndex, return the rowIndexth (0-indexed) row of the Pascal's tria ...