您的位置:首页 > 编程语言 > Java开发

Java中final 关键字相关 JVM编译static,final

2012-10-23 14:44 344 查看
我还是老习惯,最上来讲下我遇到的问题吧 问题是关于3个简单的程序,他们之间的变化甚微,但是结果有些出忽意料让我们来看看这3个程序吧第一个程序

public class Test01 {


public static void main(String[] args) {


System.out.println("Test01 main invoke: num = " + Test02.num);




}


}




class Test02 {


static {


System.out.println("Test02 static block: num = " + Test02.num);


}


static int num = 5;


}第2个程序

public class Test01 {


public static void main(String[] args) {


System.out.println("Test01 main invoke: num = " + Test02.num);




}


}




class Test02 {


static {


System.out.println("Test02 static block: num = " + Test02.num);


}


final static int num = 5;//第一个程序中这个变量不是final的,还记得吗?


}


第3个程序,其实并不是问题的根源,而是我本人遇到这样的问题时,自己给出的一个思考方法而已.我等会再说这个程序的意义在哪里



public class Test01 {


public static void main(String[] args) {


System.out.println("Test01 main invoke: num = " + Test02.num);


System.out.println(new Test02().num); //从第2个程序中读出来的


}


}




class Test02 {


static {


System.out.println("Test02 static block: num = " + Test02.num);


}


final static int num = 5;


}


然后我们分别来告诉下大家他们的输出结果好嘛

//第一个程序的


Test02 static block: num = 0


Test01 main invoke: num = 5






//第2个程序的


Test01 main invoke: num = 5




//第3个程序的


Test01 main invoke: num = 5


Test02 static block: num = 5


5


第一个程序其实很简单,为什么呢,因为static{}中间用到了下面的static的变量,此时他仅仅被赋了默认值0,所以就是0和5的输出我们所迷惑的是为什么第2个程序只有1个程序,他明明也用到了第2个类.我们也知道,一旦一个类被用到,我们就需要首先加载他的static内容.But Why?What we have done to program is just adding a final keyword.但是不要着急,我不是还写了第3个程序了嘛那么我生成一下第2个类的对象,而此时,我们的静态块中的输出终于千呼万唤始出来.等等等等,为什么你刚才调用了这个属性,我来找找是这个Test02.num..对,就是这个了,不是也用到了第2个类了吗?为什么这个时候没有执行加载静态块呢,你不是忽悠我呢吧!!!好吧,我没有忽悠你,如果是谁忽悠了你,那就是编译器了.与我无关,我也在跟你一起研究这个问题呢既然我没有忽悠你,你就该静下来好好想想,恩,

System.out.println(new Test02().num);这个才是真正用到了第2个类,那就是说,上面的调用

System.out.println("Test01 main invoke: num = " + Test02.num);根本就没有用到第2个类嘛....你说呢也许是对的,但是程序怎么知道我把Test02.num设置为5了,而不是1,2,3或者其他任何的int型呢?还记得嘛,第2个程序把这个变量已经声明成final的了,但是这有什么区别吗?Does it make someting different? 你不要鄙视我哦,至今为止我也不知道这个问题的准确答案呢.于是我去找《thinking in java》中间有关final的章节,好吧,是英文的,我先打出来,一会我会简单翻译下的 根据上下文环境,Java的关键字final的含义存在着细微的差别,但通常它指的是:“这是无法改变的”,不想做改变基于两种理由:设计或效率,由于这两个原因相差很远,所以关键字final有可能被误用。可能使用final的情况包括三种:数据、方法和类1)final数据: 许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的。有时数据的恒定不变是很有用的,比如: 1、一个永不改变的 编译期常量。 2、一个在运行时被初始化的值,而你不希望它被改变。对于编译期常量这种情况,编译器可以将该常量值代入任何可能用到它的计算式中,也就是说,可以在编译时执行计算式,这就减轻了运行时的负担,在java中,这类常量必须是基本数据类型,并且以关键字final表示。在对这个常量进行定义的时候,必须对其进行赋值。一个既是static又是final的域只占据一段不能改变的存储空间。当对 对象引用而不是基本数据类型运用final时,其含义会有一点令人迷糊。对于基本数据类型,final使其数值恒定不变,而对于对象引用,final 使其引用恒定不变。一旦引用被初始化指向对象就无法再把它改为指向另一个对象。然而对象自身是可以修改的。Java 并未提供使任何对象很定不变的途径。这一限制适用数组,数组也是对象。----引自《java 编程思想》 page 140有时间多翻翻 这本书吧,会有很多好的收获,可惜英语不好。。。

blank finals //不对


final method //也不对


final class //我靠,我要的段落呢,跑哪去了。。。有多远给我滚多远,再不出来我就火了啊


final data //真是的,总算找到了


//让我们看看他是怎么说的吧 好不容易找到了


A constant is useful for two reasons:


1. It can be a compile-time constant that won't ever change


2. It can be a value initialized at run time that you don't want changed


In the case of a compile-time constant, the compiler is allowed to "fold" the constant value into any calculation in which it's used;that is ,the calucalation can be performed at compile time ,eliminating some run-time overhead. In java, these sorts of constants must be primitives and are expressed with final keyword. A value must be given at the time of defination of such a constant.


//哈哈,够了,我们终于找到我们要的东西了


//正如我前面许诺的,我要翻译一下的对吧。。。原谅我蹩脚的英语水平


在2种情况下一个恒量(永远不变的)会是有用的:


1。 可能是编译时就确定了值的恒量


2。 可能是需要到运行时才能确定值的恒量


在第一种情况下,编译器会拿着这个恒量,把所有牵涉这个恒量的计算都计算出来


这里我要打个岔,稍微解释下什么意思呢?


比如说


static final int a=10;


int b=a+10;


这一步会在编译的时候就做好,也就是在class中间是int b=20;你必须要知道的是,像10这样的数字也算是恒量哦~~~~这个是我没解释清楚。。请你原谅我。不过他们本来就满足啊。。。一个数字10又不是一个变量。。。你能希望他变成啥呢




再下面的就是一些关于这样的恒量需要满足什么条件了:必须是原型变量,在声明时必须被赋值

哈哈,有猜想,有证明。。。不正如高中老师所说的嘛。。。西西,大胆的假设,细心的证明好了,我们得到结论了呢,也就是说在编译阶段我们的这段代码

System.out.println("Test01 main invoke: num = " + Test02.num);已经被替换掉了,替换成了

System.out.println("Test01 main invoke: num = " + 5);所以,根本就没有用到第2个类的内容,所以我们不需要加载第2个类,也就不用执行静态块的代码了,同样也就没有预期的输出了证明完毕了。。。西西,有成就感
转自:http://blog.csdn.net/nihuajie05/article/details/2343900
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java