Chinaunix首页 | 论坛 | 博客
  • 博客访问: 358099
  • 博文数量: 14
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 466
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-14 13:42
文章分类

全部博文(14)

文章存档

2009年(3)

2008年(11)

我的朋友

分类: Java

2008-04-19 22:36:55

1.static修饰一个属性字段,那么这个属性字段将成为类本身的资源,public修饰为共有的,可以在类的外部通过test.a来访问此属性;在类内部任何地方可以使用.如果被修饰为private私有,那么只能在类内部使用.
  public class Test{
public static int a;
private Test(){
a=0;
}
}
  如果属性被修饰为static静态类资源,那么这个字段永远只有一个,也就是说不管你new test()多少个类的对象,操作的永远都只是属于类的那一块内存资源.例如:
  Test t1=new Test();
t1.a=10;
Test t2=new Test();
System.out.println(t1.a);
System.out.println(t2.a);
System.out.println(Test.a);
  结果是3个0
  2.final 用于声明属性,方法和类,分别表示属性一旦被分配内存空间就必须初始化并且以后不可变,方法一旦定义必须有实现代码并且子类里不可被覆盖,类一旦定义不能被定义为抽象类或是接口,因为不可被继承。
  而你的代码里对final修饰的属性进行了修改,所以错误.
  3. 被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;
}
}
  4.同时被final和static修饰的类的属性变量只能在两种情况下初始化:
  a.在它被定义的时候,例:
  public class Test{
public final int a=0;
private Test(){
}
}
  b.在类的静态块里初始化,例:
  public class Test{
public final int a;
static{
a=0;
}
}
  5.分析第三第四原因:
  第三条:当这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源,当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是定义了一个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时执行了构造函数,所以属性被初始化了,也就符合了当它被分配内存空间的时候就需要初始化,以后不再改变的条件.
  第四条:当类的属性被同时被修饰为static和final的时候,他属于类的资源,那么就是类在被加载进内存的时候(也就是应用程序启动的时候)就要已经为此属性分配了内存,所以此时属性已经存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值.而构造函数是在当类被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化.程序就会报错.而static块是类被加载的时候执行,且只执行这一次,所以在static块中可以被初始化.
 
————————————————————————————————————————————————
令一篇文章解释:
 
看languageSpec,上说,final变量的初始化分三种情况:
共性:
1。final在初始化之后,就不能再赋值了,也就是说,它们只能被赋值一次
2。一般情况下是定义时直接初始化如:final int i=3;
但也可以定义时不初始化,叫blank final,如 final int bi;
然后留待后面进行赋值。但这因三种情况而不同:
1。普通auto变量(就是如方法中的局部变量):可以在其后的代码中赋值,
但也可以不赋值。
final int i;//blank final
anything();
i=1;//在其后赋值。
//i=3; error!不可再次赋值

而成员变量必须被赋值,只是赋值的地方不同:
2。静态成员变量:
静态成员变量必须在静态构造代码中初始化,
static final int s;
static { s=3;}//静态构造块
//static final int s; error!

3。非静态成员变量:
必须在构造函数中被赋值。如:
final int ai;
{ ai = 3; }//这种叫什么的,估且称之为实例初始化块吧(instance
initializer)
public Contructor(){ai=3;}//构造函数中
public Contructor(int in){ai=in;}//构造函数中

注意构造函数可以会有互相调用,注意在这过程中不要使变量被重复的赋值。

另外,如果变量是对象或数组这样的引用类型。则可以操作其对象或数组,但不可以
改变引用本身:
final int [] array={1,2,3};//一个由三个数字组成的数组。
array[1]=9;//array == {1,9,3}
// array=new int[6]; error!

下面是一段老外的解释,比我说的清楚:)
Please go through the following information carefully. A final var
means what ? It HAS TO HAVE a final value which CAN NOT BE CHANGED ,
ONCE IT IS ASSIGNED A VALUE.
So having said that, there are 2 types of final vars. 1. instance
final vars. 2. class level (static) final vars. instance final var
like in case 1 in the foll. example given, "final int
instFinalVar1=100" means the var instFinalVar1 has a final value as
100 throughout the instance's lifetime and we CAN NOT change its value
once we create an instance as "new Test(...)" statement.

We can maximum USE this assigned final value. In this context of this
final var discussion , I assume you know the initialization sequence
of any class. It is

1.static initialization
All static vars and static floating blocks are run first AS IN THE
SAME ORDER AS WRITTEN in the source java program.

2.instance initialization
All instance vars and instance floating blocks are run next AS IN THE
SAME ORDER AS WRITTEN in the source java program.

3.constructor is run

Let us take the instance final var case. We know that it has to have a
value and that value has to be explicitly given by the programmer. The
default values are NOT given for a final var. Even if it is a 0(zero)
value for an 'instance final int' type var, it has to be explicitly
given as "final int var1=0;" like that. So the bottomline is instance
final var has to have a value when an instance of the class is
constructed .

In the previous version of Java1.0 (I think) all instance final vars
HAVE TO BE INITIALIZED when thay are DECLARED ITLSEF. In other words
we have to write like this. "final int var1=10;". But latter in Java 2
,the designers allowed little flexiblity. What if the final var has to
have different values ACCORDING TO THE CONSTRUCTOR of the class used
to construct the instance of the class?. To allow this, they changed
the specification of the language as, "the final var has to have an
explicit value by the programmer, but it can be given either in the
declaration statement itself OR in a FOLLOWING instance floating block
(also called as instance initializers) OR in ALL CONSTRUCTORS of the
given class".

Which also means before the constructed instance is used the final
vars HAVE TO HAVE A VALUE. So we can go UPTO the constructors to init
them. Also note that if we choose to initialize an instance final var
through constructors, we have to init the var in ALL constructors. If
we think logically also, another programmer may call ANY ONE OF the
available constructors of this class to create an instance of the
class right? We can't rescrict them. So we HAVE to provide the
initializaion in ALL constructors. But the values can be anything,
need not be same.

This is story of 'instance final var' initialization and why and when
should we init them.

Simillarly for the 2nd case 'static final ' vars, the story is little
different. 'static var' means what? It is nothing to do with any
particular instance right? So , this static final vars also HAVE TO
HAVE a value explicitly assigned by the programmer and this init has
to happen either in the declaration statement itself like 'static
final int var1=100;' OR in one of FOLLOWING static floating blocks
(also called as static initializers). Also note that in both cases
instance final var and static final vars, once we assigned a value
means we CAN'T CHANGE them again. That the meaning of 'final' keyword
right?. Since static final vars are common for the class as a whole,
the init of static final vars has to happen only in the 2 cases
explained in this paragraph. They can't be assigned a value in
constructors as we have seen in the case of instance final vars.

Also please go through the following example code carefully. This code
explains what I have written here. Also feel free to ask anything at
all.

regds
maha anna


class Test { //case 1 final int instFinalVar1 = 100; //This
is ok //case 2 final int instFinalVar2; {
//init in instance floating block instFinalVar2 = 200;
//This is ok } //case 3 final int instFinalVar3;
Test(){ /* We MUST init the instance final var in
ALL constructors of this class ,since instFinalVar3 is NOT
INITIALIZED either in declaration or in any instance
floating blocks. (also called as instance initializers)
*/ instFinalVar3=10; //instFinalVar3=100;
//THis is NOT ok . Once we assign a value to a final var we CAN NOT
//chnage it afterwards } //constructor 2 Test(String s) {
/* We MUST init the instance final var in ALL
constructors of this class ,since instFinalVar3 is NOT
INITIALIZED either in declaration or in any instance
floating blocks. (also called as instance initializers)
*/ instFinalVar3=20; } //constructor 3
Test(int i) { /* We MUST init the instance
final var in ALL constructors of this class ,since
instFinalVar3 is NOT INITIALIZED either in declaration or
in any instance floating blocks. (also called as
instance initializers) */ instFinalVar3=30;
} //case 4 static final int staticFinalVar1 = 10; //this
is ok//case 5 static final int staticFinalVar2; static{
/*init in static floating block and this has to be
written AFTER this "static final int staticFinalVar2;"
declaration statement in the source java program file.
Otherwise forward reference problem occur. This holds
true for case2 also. Check the foll case6. */
staticFinalVar2 = 200; //This is ok }//case 6 static{ /*init
in static floating block and this has to be written AFTER this
"static final int staticFinalVar3;" declaration statement in the
source java program file. Otherwise forward reference problem
occur. This holds true for case2 also. */ staticFinalVar3 = 300;
//This is NOT ok } static final int staticFinalVar3;
//THis is NOT ok //This declaration has to be written before
the above //static floating block (also called as static
//initializing block)}
For local final variable , delay initialization is permitted.

阅读(1534) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-09-02 09:56:07

讲得好极啦 清晰明了