final修饰符

1.  对一个final变量,不管它是类变量、实例变量,还是局部变量,只要定义改变量时使用了final修饰符修饰,并在定义该final类变量时指定了初始值,而且该初始值可以在编译时就被确定下来,那么这个final变量本质上已经不再是变量,而是相当于一个直接量。
     
 
2  final修饰符的一个重要用途就是定义“宏变量”。当定义final变量时就为该变量指定了初始值,而且该初始值可以在编译时就确定下来,那这个final变量本质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方直接替换成改变量的值。
  
 
3.  除了上面那种为final变量赋值时赋直接量的情况外,如果被赋的表达式只是基本的算术运算表达式或字符串连接运算,没有访问普通变量,调用方法,java编译器同样会将这种final变量当成“宏变量”处理。
注意:java会缓存曾经用过的字符串直接量。例如执行String a="java";语句之后,系统的字符串池中就会缓存一个字符串"java"字符串;如果程序再次执行String b="java";系统将会让b直接指向字符串池中的"java"字符串,因此a==b将会返回true。
               -->请参考    例三
 
4. 对于实例变量而言,除了可以在定义该变量时赋初始值之外,还可以在非静态初始化块、构造器中对它赋初始值,而且在这3个地方指定初始值的效果基本一样。但对于final实例变量而言,只有在定义该变量时指定初始值才会有“宏变量”的效果,在静态初始化块、构造器中为final实例变量指定初始值则不会有这种效果。 
注意:在这里是说,如何初始化能让final实例变量有“宏变量”的效果,不是说final实例变量可以在哪进行初始化。
              
 
5. 怎样才能在编译时就确定变量的值?
    由 1、2 可知,
实例: 
   例三:
   
public class StringJoinTest{
   public static void main(String[] args){
       String s1="疯狂的java";//字符串池缓存了一个字符串"疯狂的java"
       String s2="疯狂的"+"java";//编译时就确定了值为"疯狂的java",所以直接指向字符串池中的缓存字符串"疯狂的java",此时s1 跟 s2 的内存地址是一样的
       System.out.println(s1==s2);
       //定义2个字符串直接量
       String str1="疯狂";
       String str2="java";
       //将str1和str2进行连接运算
       String s3=str1+str2;//使用了普通变量,所以编译时无法确定值,在运行时,在内存独自开一块内存空间,存储值.此时的s3内存地址是跟s1不一样的
       System.out.println(s1==s3);
   }
}
 
             
 
原文地址:https://www.cnblogs.com/JamKong/p/4447192.html