`

Java中静态变量的初始化问题

 
阅读更多
/**
* java中的内存有一块地址叫"静态代码区",所有静态类都是放在这里的,静态类随jvm启动后就在那
* <p>
* 不会说程序停止了,它就被垃圾回收器回收,而new是实例化的命令,它会在java中的内存中的堆区,
* <p>
* 创建一个对象,注意它们的位置,一个是在 静态代码区,一个是在堆区,new出来的对象,一旦程序运行完,
* <p>
* 它就会被垃圾回收器回收.静态的,是不会消失了,只要jvm不关,就在一直在那.
*/
下面通过一个例子来加深对java静态变量的理解,这个例子相信想进一步了解java静态变量的同学,在很多地方都看见过:)

Order.java文件:
package com.ex;

public class Order {

	static Cupboard t1 = new Cupboard();

	static Table t2;

	Bowl t3 = new Bowl(10);

	void print() {
		t3.f1();
	}

	public static void main(String[] args) {
		System.out.println("Creating new Cupboard() in main");
		new Cupboard();
		System.out.println("Creating new Cupboard() in main");
		Order od = new Order();
		od.t3.f1();
		Table t4 = new Table("aa", 1);
	}

}


Bowl.java文件:
package com.ex;

public class Bowl {
	
	Bowl(int marker) {
		System.out.println("Bowl(" + marker + ")");
	}

	void f1() {
		System.out.println("Ok");
	}

}


Cupboard.java文件:
package com.ex;

public class Cupboard {

	Bowl b1 = new Bowl(1);

	/** 先static后非static变量初始化的顺序原则开始初始化各个变量. */
	static Bowl b2 = new Bowl(2);

	Cupboard() {
		System.out.println("Cupboard()");
	}

	static Bowl b3 = new Bowl(3);

}


Table.java文件:
package com.ex;

public class Table {
	
	Table() {
		System.out.println("Table()");
	}

	Table(String a, int i) {
		this();
		System.out.println("Ok");
	}

}


运行结果:
Bowl(2)
Bowl(3)
Bowl(1)
Cupboard()
Creating new Cupboard() in main
Bowl(1)
Cupboard()
Creating new Cupboard() in main
Bowl(10)
Ok
Table()
Ok


分析:
    首先程序从public类开始,装载Order,class,运行
     static Cupboard t1 = new Cupboard();
    由于t1是一个对象引用变量,首先得到初始化,然后转到Cupboard类的实例中,这时候程序开始初始化该实例中的变量,按照先static后非static变量初始化的顺序原则开始初始化各个变量,此时:
    static Bowl b2 = new Bowl(2);
    static Bowl b3 = new Bowl(3);
    这两块先得到初始化,然后   
    Bowl b1 = new Bowl(1);得到初始化(注意,这是非stataic变量)
    然后转到Cupboard() 构造函数.此时Cupboard类已经初始化完毕,程序返回到public类中,又发现有 static Table t2;开始初始化,由于t2只是个声明的变量,并没有创建一个Table对象让它指向,因此不要管这个t2变量.在public类中,由于此时再没有static变量可以初始化,那么程序转到static方法main中进行,(注意:Bowl t3 = new Bowl(10); 这一句为什么得不到初始化,是因为此时没有创建类Order的实例,所以程序目前还不会初始化该代码,至于以后会不会初始化,还要看在main方法中是否会创建Order类的实例,如创建了,则一定初始化,否则不会.)
在main方法中,System.out.println("Creating new Cupboard() in main");//首先打印该行要输出的语句new Cupboard();   //创建了Cupboard类的实例,程序转到Cupboard中进行变量初始化,此时要注意:   
    static变量的初始化,它只能初始化一次,也就是说,如果前面已经初始化过了,那么此时就不必要再初始化了.
分享到:
评论
1 楼 edison_cool911 2011-10-24  
连我都看的懂,相信一般的同学都看的懂了,O(∩_∩)O哈哈~

相关推荐

    Java类加载器:静态变量初始化.docx

    这篇文章将深入探讨 Java 类加载器中的静态变量初始化机制,了解其背后的工作原理和载入过程。 静态变量初始化机制 ------------------ 在 Java 中,静态变量是指在类加载时初始化的变量。静态变量的初始化是由类...

    Java中static静态变量的初始化完全解析

    ### 静态变量初始化的基本规则: 1. **默认初始化**:当类被加载时,静态变量首先会被赋予其数据类型的默认值。例如,`int`类型的静态变量会被初始化为`0`,`boolean`为`false`,引用类型为`null`。 2. **显式初始化...

    关于Java静态成员变量和静态初始化块等的初始化顺序的详细介绍

    详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序

    学习java静态数据初始化.doc

    在 Java 中,静态数据初始化是指在类加载过程中对静态变量的初始化。静态变量是在类加载时被初始化的,而不是在实例创建时。静态变量的初始化顺序是按照它们在类中的定义顺序进行的。 在 Java 中有两种类型的变量:...

    Java变量初始化

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

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

    总之,理解并有效地使用静态和对象初始化块是Java开发中的关键技能,它们可以帮助我们更好地控制类和对象的初始化过程,确保代码的高效性和正确性。在实际编程中,我们应该根据需求谨慎选择合适的初始化策略,以优化...

    java类变量初始化顺序

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

    java中静态与非静态的变量定义与使用

    这强调了静态变量初始化时可以执行的方法调用,而这些方法调用是在任何对象创建之前进行的。 此外,注意到 `main` 方法中 `t2.f2(1)` 和 `c1.f3(1)` 的调用。由于 `t2` 和 `c1` 是静态变量,我们可以直接通过它们...

    java中类的初始化顺序

    // 静态成员变量初始化 public static TestA a = new TestA(); // 静态初始化块 static { System.out.println("静态初始化"); } // 实例成员变量初始化 public static TestB b = new TestB(); public ...

    Java中的静态变量静态方法静态块与静态类.docx

    在静态块中,我们通常进行一些需要进行异常捕获的静态变量的初始化。 例如: ```java public class StaticExample { static { System.out.println("StaticExample static block"); str = "Test"; setCount(2);...

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

    同时,掌握类变量初始化顺序可以避免因误解而导致的错误,特别是在多线程环境中,对静态变量的并发访问和初始化顺序的控制需要特别注意。 总之,深入理解Java的ClassLoader机制和类变量初始化顺序是提升Java编程...

    Java静态和非静态成员变量初始化过程解析

    Java静态和非静态成员变量初始化过程解析是Java语言中一个非常重要的概念。了解Java静态和非静态成员变量的初始化过程对大家的学习或者工作具有一定的参考学习价值。 首先,我们需要了解什么是静态成员变量和非静态...

    php 静态变量的初始化

    然而,如果你想要将静态变量初始化为一个对象,PHP并不支持像Java那样的静态构造器或静态初始化块。在这种情况下,你需要在代码的某个时刻显式地调用一个方法来完成初始化。例如: ```php class A { static ...

    java数组初始化详解

    在 Java 中,数组的初始化可以分为静态初始化和动态初始化。 静态初始化是指在定义数组时同时初始化数组的值,例如:`int[] a = {1, 2, 3};`。 动态初始化是指在定义数组时不初始化数组的值,而是在后续的代码中...

    Java static静态初始快

    下面是一些关于Java静态初始化块的关键知识点: 1. **执行顺序**:静态初始化块在非静态初始化块之前执行。当类第一次被加载时,JVM会按照它们在源代码中的顺序执行静态初始化块。 2. **类加载机制**:Java类的...

    java代码的初始化顺序demo

    总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...

    java 静态非静态 字段方法 子类父类构造_初始化顺序!

    java 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...

    static静态变量使用@Value注入方式.md

    静态变量在类加载时就已经初始化完毕,而Spring Bean的初始化通常发生在应用程序启动过程中,两者的时间点不同步。因此,直接在静态变量上使用`@Value`会导致注入失败,并且在编译或运行时出现警告或错误信息。 ###...

Global site tag (gtag.js) - Google Analytics