`
南山忍者
  • 浏览: 86093 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中的初始化顺序

    博客分类:
  • Java
 
阅读更多

 

     【自己现在的一些疑问记录在这儿,如果你是Java初学者,请跳过。如果你是高手,也请教和指正里面的不足,谢谢】

 

     现在才感觉到自己有多么的菜,所以在这儿写一下关于Java的一些认识和想法。

 

1,对于static的理解。

 

     静态类其生命周期。在单例模式中,其用的就是static的特性。单例模式比较好理解。就是使其构造器成为私有的,这样才能够做到,其他的人不能随便的构造该类的实例。但是这个就有一个关于static 的声明周期的问题,即,静态对象的生命周期从什么时候开始的,到什么时候结束。一般的类对象,只要没有引用或者闭环的引用,垃圾回收器会自动的将其回收(当然,什么时间回收,这是垃圾回收器自己的决定,甚至等到最后垃圾回收器也不会回收该对象)。

    那么,这儿就有一个疑问,静态对象是什么时候开始的,和什么时候它该结束呢?

 

    先来回答第一个问题。静态对象的生命周期是什么时候开始的。

 

    举个例子:

 

 

class Test1{
	static {
		int i = 0;
		System.out.println("这个是静态的语句块,观察其生命周期的开始!"+i);
	}
}

public class MyTest0001{

	public static void main(String[] args){
		System.out.println("这个是MyTest0001中的输出!");
	}
}

 

上面的这个例子中,在MyTest0001.java中没有用到任何的Test1,所以这个时候的Test1中的静态语句块肯定是不会执行的,但是,如果在MyTest0001中做一下两种改变,则其将会执行static的语句块。

 

 

 

public class MyTest0001 extends Test1{

	public static void main(String[] args){
		System.out.println("这个是MyTest0001中的输出!");
	}
}

 

这个是MyTest0001继承了Test1,则将会输出 Test1中的打印语句。

 

 

 

public class MyTest0001 {

	public static void main(String[] args){
		Test1 a= new Test1();
		System.out.println("这个是MyTest0001中的输出!");
	}
}
 

这个是在main方法中实例化该对象,这个显然是要输出的Test1中的内容的。

 

其实本人现在还是有点晕,静态对象/变量的生命周期到底是一个什么情况,也请大家指教和相互的讨论~~

 

 

2,继承与初始化

 

总的来说初试化的过程如下:

 

首先:加载父类,然后子类。第二步:父类的static的初始化,然后是子类的static初始化。

第三步:必要的类都已经加载完毕,对象就可以创建了。首先对象中所有的基本类型都会被设置为默认值,对象的引用被设置为null。然后父类的构造器将被调用。然后是子类的变量的初试化,然后是子类的构造器。

 

 

//这个例子主要是用来说明初始化的顺序的

class  Test0002{
	private int i = 1;

	protected int j;

	public Test0002(){
		System.out.println("i="+i+", j= "+j);
		j = 2;	
		System.out.println("i="+i+", j= "+j);	
	}

	static{
		System.out.println("父类中的static语句块的初始化");
	} 

	private static int x1 = printInt("这个是父类Test0002中的x1的初始化");

	private int x11 = printInt("这个是父类Test0002中的x11的初始化");

	static  int printInt(String s){
		System.out.println(s);
		return 10;
	}
} 


public class MyTest0002 extends Test0002{
	private  int x2 = printInt("这个是子类MyTest0002中x2的初始化");

	public MyTest0002(){
		System.out.println(x2);
		System.out.println(j);
	}
	
	private static int x3 = printInt("这个是子类MyTest0002中x3的初始化");
	

	public static void main(String[] args){
		System.out.println("创建MyTest0002对象");
		MyTest0002 a = new MyTest0002();
	}

}
   

 

如果看这段代码,其输出结果是什么呢?

 

  其结果为:父类中的static语句块的初始化

                 这个是父类Test0002中的x1的初始化

                 这个是子类MyTest0002中x3的初始化

                 创建MyTest0002对象

                 这个是父类Test0002中的x11的初始化

i = 1, j = 0

  i = 1, j = 2

    这个是子类MyTest0002中x2的初始化

10

  2

 

 

这个例子也说明了在继承以及初始化的过程。

 

首先:先初始化父类中的static变量修饰的语句块和变量(在本例中就是先初始化:

 

static{

System.out.println("父类中的static语句块的初始化");

}  和 

 

private static int x1 = printInt("这个是父类Test0002中的x1的初始化");

(这儿也要注意一点,因为x1变量是一个静态的变量,所以给其赋值的方法也必须是静态的方法。如果将printInt(String s)前面的static去掉,则编译期间会出错,相关的知识请参考static的知识点)

   

 

这儿还需要注意的另一点:在父类中有一个变量:

 

private int x11 = printInt("这个是父类Test0002中的x11的初始化");

 

虽然printInt(String s)是一个静态的方法,但是x11是一个非静态变量,所以此时将不会对其初始化。

 

第二步,就是初始化子类中的static语句块或者变量。

 

即将会初始化:private static int x3 = printInt("这个是子类MyTest0002中x3的初始化");

所以输出结果中的前三条就是:

 

 父类中的static语句块的初始化

                 这个是父类Test0002中的x1的初始化

                 这个是子类MyTest0002中x3的初始化

 

第三步就是要使用构造器创建对象了。(即将父类和子类中静态的变量和语句块执行完之后,就开始要创建对象了,所以就要进入main方法中进行了)

 

所以下一步的输出就是:

 

  创建MyTest0002对象

 

但是在创建对象的时候,因为还有一个父类,所以一定要先初始化父类,所以执行到这一步的时候就会跳到父类,去创建父类的对象,

 

 

分享到:
评论

相关推荐

    java程序初始化顺序

    以下是对Java程序初始化顺序的详细说明: 1. **类加载阶段**: - **加载**:当Java虚拟机(JVM)首次遇到一个类的引用时,会通过类加载器进行加载。加载过程包括找到类的.class文件,读取其字节码,并转化为内存中...

    详解Spring 中如何控制2个bean中的初始化顺序

    Spring 中控制 2 个 bean 的初始化顺序 在 Spring 框架中,控制多个 bean 的初始化顺序是一个常见的问题。本篇文章将详细介绍如何控制 2 个 bean 的初始化顺序,提供了多种实现方式,并分析了每种方式的优缺。 ...

    java面试题-类的初始化顺序.doc

    在实际开发中,理解这个初始化顺序是非常重要的,尤其是在设计复杂的类结构或者涉及单例模式、线程安全初始化等场景时。如果在构造器或初始化块中依赖其他静态或非静态成员,必须确保这些成员在需要之前已经被正确...

    Java类继承初始化顺序

    当我们谈论“Java类继承初始化顺序”时,涉及到的关键知识点包括构造器、成员变量的初始化、super关键字以及方法的覆盖。 首先,了解类初始化的顺序至关重要。当创建一个子类实例时,初始化过程遵循以下步骤: 1. ...

    java代码的初始化顺序demo

    让我们深入探讨Java中的初始化顺序及其背后的机制。 1. **类加载阶段**: 在Java程序运行时,JVM会先加载类的字节码文件(.class文件)。这个过程包括加载、验证、准备、解析和初始化五个步骤。这里我们主要关注...

    “礼让”原则学习Java对象初始化顺序.pdf

    Java 对象初始化顺序是指在 Java 程序中,对象的初始化过程中发生的顺序问题。这是 Java 编程语言的基础知识点之一,但是许多学生在学习和使用时总是感到困惑和困难。 二、JVM 执行过程中的“礼让”原则 JVM 在...

    java中类的初始化顺序

    ### Java中类的初始化顺序详解 #### 一、概述 在Java编程语言中,类的初始化是一个非常重要的概念。类的初始化涉及到多个方面,包括静态成员变量、实例成员变量、静态初始化块、实例初始化块以及构造函数等。本文...

    java类变量初始化顺序

    详细讲解java类中静态变量,普通标量,对象、基本类型的初始化顺序。

    Java初始化顺序1

    Java 中的初始化顺序是按照定义的顺序进行的,而静态变量的初始化顺序则是按照定义的顺序,并且只在第一次访问时初始化。 Java 初始化顺序的知识点总结: * 类变量(静态变量)和实例变量(对象变量)的区别 * ...

    类继承的初始化顺序类,继承的初始化顺序

    在面向对象语言中(如Java、C#等),当创建一个继承自某个基类的子类对象时,会有一个特定的初始化顺序。这个顺序通常遵循以下步骤: 1. **基类静态成员初始化**:如果基类中有任何静态成员,则会在程序启动时按照...

    C++和Java初始化顺序的比较代码

    在Java中,初始化顺序则有所不同: 1. 基本类型的静态字段和引用类型的静态字段(如果它们是常量,即final且已初始化):这些字段在类加载时按声明顺序初始化。 2. 静态初始化块:当类第一次被加载时执行,按块的...

    java类中静态域、块,非静态域、块,构造函数的初始化顺序

    ### Java 类中静态域、块,非静态域、块,构造函数的初始化顺序 #### 一、概述 在 Java 编程语言中,类的初始化顺序对于理解程序的行为至关重要。特别是当涉及到静态域(静态变量)、非静态域(实例变量)、静态块...

    Java静态初始化块和对象初始化块

    在Java编程语言中,初始化块是程序执行时用于初始化对象或类的重要机制。这里我们将深入探讨两种类型的初始化块:静态初始化块(Static Initializer Block)和对象初始化块(Instance Initializer Block)。这两种...

    探究java的ClassLoader及类变量初始化顺序

    Java中,类变量(static变量)的初始化顺序遵循以下规则: 1. 首先,执行父类的静态初始化块(方法),如果有的话。 2. 然后,执行子类的静态初始化块。 3. 静态变量的初始化顺序取决于它们在代码中声明的顺序,而...

    JAVA面试题解惑系列——类的初始化顺序

    在Java中,类的初始化顺序是一个经常被问及的面试题目,尤其对于Java程序员和工程师来说,了解这个知识点是必须的。在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面...

    Java变量初始化

    Java 变量初始化的时机是指在 Java 语言中变量的初始化过程,包括变量的声明、初始化和赋值的步骤。 Java 变量声明 在 Java 语言中,每个变量必须先声明,然后才能使用。声明变量时必须指定该变量的数据类型。...

    Java初始化顺序

    作为一名程序员必须知道Java初始化顺序......

    java类中元素初始化顺序详解

    在 Java 中,类的元素初始化顺序遵循以下规则: 1. **静态变量与静态初始化块**: 首先,Java 解释器会执行类中的静态变量初始化和静态初始化块。这些静态元素的初始化只会在类加载时执行一次,并且按照它们在源...

    JAVA类的初始化顺序文.pdf

    子类 --构造器 这个输出揭示了在继承关系中类的初始化顺序: 1. **静态成员和静态初始化块**:首先,会按照父类到子类的顺序初始化静态变量和执行静态初始化块。在上面的例子中,"父类 --静态变量" 和 "子类 --静态...

Global site tag (gtag.js) - Google Analytics