`
zhuxiaoqiu
  • 浏览: 46621 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java基础知识温习系列一:Static

阅读更多
说明:最近在看臧圩人的博客(http://zangweiren.iteye.com),他的博客在年度排行榜上排第4位,是为很厉害的人物,写的博客内容也非常不错,简单易懂而不失深度,特别是他的Java面试题解惑系列。我看这个解惑系列,然后对基础知识再梳理了一次。这个温习系列里面的大部分内容和代码均来自臧圩人的面试题解惑系列。

对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:
public class InitialOrderTest {
	// 静态变量
	public static String staticField = "静态变量";
	// 变量
	public String field = "变量";
	// 静态初始化块
	static {
		System.out.println(staticField);
		System.out.println("静态初始化块");
	}
	// 初始化块
	{
		System.out.println(field);
		System.out.println("初始化块");
	}
	// 构造器
	public InitialOrderTest() {
		System.out.println("构造器");
	}
	public static void main(String[] args) {
		new InitialOrderTest();
	}
}

运行以上代码,我们会得到如下的输出结果:
静态变量
静态初始化块
变量
初始化块
构造器

这种结果的原因是什么呢?实际上就是对关键字static的理解。用static修饰的成员变量或者成员方法是依赖类而存在的。要使用普通的成员变量或者方法,首先要new出一个对象来,然后在借助这个对象来调用成员变量或者方法。而使用static修饰的变量或者方法可以采用classname.instancevariable或者classname.methodname()的形式来调用。最典型的就是main()方法,因为它是程序的入口,这时还没有任何对象被创建,所以main()方法要被标记为static。
换句话说就是,使用static修饰的元素(可以是实例变量、方法或者代码块)是和类一起同生共死的。在类加载器加载类的时候就会初始化这些static元素。所以在初始化的时候static元素就会放在第一位。
对于变量和初始化块的顺序可以这样理解,变量的初始化顺序肯定在初始化块的前面。因为初始化块中要用到变量,所以如果变量没有先初始化,那怎么用得了呢?
至于构造方法肯定是在最后的。因为它是在new一个对象的时候构造方法才会被调用。类的加载,实例变量的初始化完成等等工作都OK了,才有可能用new来创建对象啊。所以,构造方法是在最后面的。
相关的话题是,在类继承时父类和子类的这些东东的顺序会是怎样的呢?下回再表。已经是凌晨1点20分了,昏觉了
分享到:
评论
2 楼 oyprunner 2009-04-09  
反编译的结果:
Compiled from "Test.java"
public class Test extends java.lang.Object{
public static java.lang.String staticField;

public java.lang.String field;

public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   ldc     #2; //String 变量
   7:   putfield        #3; //Field field:Ljava/lang/String;
   10:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   13:  aload_0
   14:  getfield        #3; //Field field:Ljava/lang/String;
   17:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
   20:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   23:  ldc     #6; //String 初始化块
   25:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
   28:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   31:  ldc     #7; //String 构造器
   33:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
   36:  return

public static void main(java.lang.String[]);
  Code:
   0:   new     #8; //class Test
   3:   dup
   4:   invokespecial   #9; //Method "<init>":()V
   7:   pop
   8:   return

static {};
  Code:
   0:   ldc     #10; //String 静态变量
   2:   putstatic       #11; //Field staticField:Ljava/lang/String;
   5:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   8:   getstatic       #11; //Field staticField:Ljava/lang/String;
   11:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
   14:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   17:  ldc     #12; //String 静态初始化块
   19:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
   22:  return

}
1 楼 wangzaixiang 2009-04-02  
呵呵,理解基本正确。不过,了解的方法却不甚有效。

给你推荐一个方法,使用javap -c 反编译你的代码,然后你就会更加明白为什么会这样。如果看不懂的话,推荐买一本Java虚拟机的书放在旁边翻翻。

不过说老实话,这样研究技术,很难的,当务之急,还是尽快去做一些实际的项目、写一些有目标的代码,这样才能培养感觉。别钻这些太深了,却没有实践经验。

相关推荐

Global site tag (gtag.js) - Google Analytics