JAVA 中的static、final

 

1、static

如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main(),所以它被声明为static。

有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static成员的最常见的例子是main( )。因为在程序开始执行时必须调用main(),所以它被声明为static。

 

static变量:

声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量,也就是说不管你new多少个类的对象,这个static变量永远只有一个。

static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。

在static后加大括号({)里面有一段代码,是用来进行显式的静态变量初始化,这段代码只会初始化一次,且在类被第一次装载时。

 

static方法:

  在一个类中定义一个方法为static,那就是说,用类名而无需本类的对象即可调用此方法,即“类名.方法名”。一般来说,静态方法常常为应用程序中的其它类提供一些实用工具所用,在Java的类库中大量的静态方法正是出于此目的而定义的。

声明为static的方法有以下几条限制:

◆它们仅能调用其他的static方法,要保持同样的生命周期;

◆它们只能访问static数据,要保持同样的生命周期;

◆它们不能以任何方式引用this或super,因为static方法不属于某个对象实例。

 

 

通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。

 

所以,static变量(方法、或者块程序)是在类被装载的时候开始执行,而不是在创建对象的时候执行。

 

 

2、final

final用于声明变量、方法和类。

final变量,表示该变量一旦被分配内存空间就必须初始化并且以后不可变;

final方法,表示该方法提供的功能已经满足你要求,不需要进行扩展,可以继承,但不可以被覆盖或改写;由于我们不能访问一个private方法,所以它绝对不会被其他方法覆盖(若强行这样做,编译器会给出错误提示),类内所有private方法都自动成为final,可为一个private方法添加final指示符,但却不能为那个方法提供任何额外的含义(个人感觉类内private方法==final方法)。

final类,表示该类不希望从这个类继承(无后代^=^),所以不能被定义为抽象类或是接口。由于它禁止了继承,所以一个final类中的所有方法都默认为final。

对于基本数据类型,final会将值变成一个常数;但对于对象句柄(引用),final会将句柄变成一个常数。进行声明时,必须将句柄初始化到一个具体的对象。而且永远不能将句柄变成指向另一个对象。然而,对象本身是可以修改的。Java对此未提供任何手段,可将一个对象直接变成一个常数(但是,我们可自己编写一个类,使其中的对象具有“常数”效果)。这一限制也适用于数组,它也属于对象。

 

被final修饰而没有被static修饰的类的属性变量只能在两种情况下初始化:

a.在它被定义的时候,例:

public class Test{

public final int a=0;

private Test(){ }

}

b.在构造函数里初始化,例:

public class Test{

public final int a;

private Test(){ a=0; }

}

原因:当这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源,当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是定义了一个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时执行了构造函数,所以属性被初始化了,也就符合了当它被分配内存空间的时候就需要初始化,以后不再改变的条件。

 

 

同时被final和static修饰的类的属性变量只能在两种情况下初始化:

a.在它被定义的时候,例:

public class Test{

public static final int a=0;

private Test(){ }

}

b.在类的静态块里初始化,例:

public class Test{

public static final int a;

static{ a=0; }

}

原因:当类的属性被同时被修饰为static和final的时候,他属于类的资源,那么就是类在被加载进内存的时候(也就是应用程序启动的时候)就要已经为此属性分配了内存,所以此时属性已经存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值,而构造函数是在当类被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化,程序就会报错,而static块是类被加载的时候执行,且只执行这一次,所以在static块中可以被初始化。

 

 

3、java中的初始化

对于初始化主要包含这几方面:static 变量 、non-static变量、构造函数、new对象建立。

1、static变量的初始化:当pulic class 被loadin(栽入)的时候,就开始对static变量初始化了,因为static 变量的refrence是存储在static storage(静态存储空间)中。此时不对non-static变量和构造函数初始化,因为还没有对象的产生,只是把某个型别loadin。注意对于static变量只初始化1次,当有新的对象产生时,他并不会重新被初始化了,也就是他的refrence已经固定,但他的值是可以改变的。

2、当有对象产生时,开始对此class(型别)内的non-static变量进行初始化,然后再初始化构造函数。产生已初始化的object对象。

3、按要求顺序执行其它函数。

4、对有继承的class(型别)来说,先初始化父类,再初始化子类。

总体思想:static变量(它们在类定义代码里写入的顺序)……non-static变量(由变量在类内的定义顺序决定的)……构造函数。

posted on 2011-11-20 17:09  张世民  阅读(1338)  评论(0编辑  收藏  举报