静态变量一定要先声明后赋值

简介:

这标题看着让人很纳闷,什么叫做变量一定要先声明后赋值?Java中的变量不都是先声明后使用的吗?难道还能先使用后声明?能不能暂且不说,我们先来看一个例子,代码如下:

复制代码
1 public class Client {  
2      public static  int i=1;  
3      static{  
4          i=100;  
5      }  
6      public static void main(String[] args) {  
7           System.out.println(i);  
8     }  
9 } 
复制代码

这段程序很简单,输出100嘛!对,确实是100,我们再稍稍修改一下,代码如下:

复制代码
 1 public class Client {
 2     static {
 3         i = 100;
 4     }
 5     public static int i = 1;
 6 
 7     public static void main(String[] args) {
 8         System.out.println(i);
 9     }
10 }
复制代码

注意,变量i的声明和赋值调换了位置,现在的问题是:这段程序能否编译?如果可以编译那输出是多少?还要注意:这个变量i可是先使用(也就是赋值)后声明的。

答案是:可以编译,没有任何问题,输出是1。对,你没有看错,输出确实是1,而不是100。仅仅调换了一下位置,输出就变了,而且变量i还真是先使用后声明的,难道这世界真的颠倒了?

这要从静态变量的诞生说起了,静态变量是类加载时被分配到数据区(Data Area)的,它在内存中只有一个拷贝,不会被分配多次,其后的所有赋值操作都是值改变,地址则保持不变。我们知道JVM初始化变量是先声明空间,然后再赋值的,也就是说:

int i=100;  
在JVM中是分开执行,等价于:  
int i;  //分配地址空间  
i=100;  //赋值 

静态变量是在类初始化时首先被加载的,JVM会去查找类中所有的静态声明,然后分配空间,注意这时候只是完成了地址空间的分配,还没有赋值,之后JVM会根据类中静态赋值(包括静态类赋值和静态块赋值)的先后顺序来执行。对于程序来说,就是先声明了int类型的地址空间,并把地址传递给了i,然后按照类中的先后顺序执行赋值动作,首先执行静态块中i=100,接着执行i=1,那最后的结果就是i=1了。

哦,如此而已,那再问一个问题:如果有多个静态块对i继续赋值呢?i当然还是等于1了,谁的位置最靠后谁有最终的决定权。

有些程序员喜欢把变量定义放到类的底部,如果这是实例变量还好说,没有任何问题,但如果是静态变量,而且还在静态块中进行了赋值,那这结果可就和你期望的不一样了,所以遵循Java通用的开发规范“变量先声明后使用”是一个良好的编码风格。

注意 再次重申变量要先声明后使用,这不是一句废话。

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/5428622.html,如需转载请自行联系原作者

相关文章
|
5月前
|
开发者
局部变量,在使用时再定义
关于局部变量,适时定义可以提高代码可读性并规避不必要的bug。示例代码中,为了避免误解`checkTaskApplyDTO`仅设置了`userId`,在`existAppliedTask`方法内部,可以通过将`checkTaskApplyDTO`的定义与设置属性的操作靠近,以明确其所有属性值的来源。 另外,本文还展示了一个因提前定义变量`ret`而导致的bug实例。如果将此变量的定义延迟至其实际使用前,则可以避免此类问题。适时定义变量有助于减少混淆,提高代码质量。
47 4
|
5月前
成员变量、局部变量和静态变量的区别
成员变量、局部变量和静态变量的区别
31 0
|
7月前
|
Java
局部变量和成员变量
局部变量和成员变量1.定义的位置不一样【重点】局部变量:在方法的内部成员变量:在方法的外部,直接写在类当中2.作用范围不一样【重点】局部变量:只有方法当中才可以使用,出了方法就不能再用成员变量:整个类全都可以通用。3.默认值不一样【重点】局部变量:没有默认值,如果要想使用,必须手动进行赋值成员变量:如果没有赋值,会有默认值,规则和数组一样4.内存的位置不一样(了解)局部变量:位于栈内存成员变量:位于堆内存5生命周期不一样(了解)局部变量:随着方法进栈而诞生,随着方法出栈而消失成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失当方法的局部变量和类的成员变量重名
|
Java
成员变量与局部变量
成员变量与局部变量
127 0
|
存储
局部变量和成员变量的4个区别
定义位置不同、内存中的位置不同、周期不同、初始化不同。
128 0
声明了一个数组变量 myList
声明了一个数组变量 myList
94 0
全局变量的声明
全局变量的声明
158 0
使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变
使用final关键字修饰一个变量时,是指引用变量不能变,但是引用变量所指向的对象中的内容还是可以改变的。
421 0
使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变
4.15.3下面的数据声明及赋值哪一个是正确的?
下面的数据声明及赋值哪一个是正确的? A. float f = 1.3; B. char c = C. byte b = 257 D. int i = 10 相关知识点: https://edu.aliyun.com/course/34 正确答案:D
341 0
|
存储 开发者 容器
声明变量并赋值|学习笔记
快速学习 声明变量并赋值
142 0