[转] 再论 java 中的 final 变量

【java中为何会有final变量】:java

final这个关键字的含义是“这是没法改变的”或者“终态的”;
那么为何要阻止改变呢?
java语言的发明者可能因为两个目的而阻止改变:
1).效率问题:
    jdk中的某些类的某些方法,是不容许被用户覆盖的,设计者可能认为,所用方法已是最好的方法,
    用户私自覆盖,或是因为疏忽而覆盖,就会影响JVM或是系统的系能;
2). 设计所需:
    众所周知,有些状况必须使用final关键字,好比方法中的匿名内部类的参数传递;

【final关键字的使用方法】:多线程

【修饰变量】:
    final成员变量表示常量,只能被赋值一次,赋值后值再也不改变。
【修饰方法】:
    final方法不能被子类方法覆盖,但能够被继承。
【修饰类】:
    final类不能被继承,没有子类,final类中全部方法都是final的。

【final的内存分配方式】:函数

【修饰变量】:
    一般状况下,final变量有3个地方能够赋值:直接赋值,构造函数中,或是初始化块中。
    【初始化】:
        因为在java的语法中,声明和初始化是联系在一块儿的,
        也就是说:若是你不显示的初始化一个变量,系统会自动用一个默认值来对其进行初始化。(如int就是0)
        对于final变量,在声明时,若是你没有赋值,系统默认这是一个空白域,在构造函数进行初始化,
        若是是静态的,则能够在初始化块。
    【内存】:
         常量(final变量)和非final变量的处理方式是不同的。
         每个类型在用到一个常量时,都会复制一份到本身的常量池中。
         常量也像类变量(static)同样保存在方法区,只不过他保存在常量池。
         (多是,类变量被全部实例共享,而常量池是每一个实例独有的。)
【修饰方法】:
    保存在方法区,而且能够被函数代码直接替换,而不用等到执行时再决定具体是那个函数。
【修饰类】:
    保存在方法区。

【java中变量的初始化顺序】:测试

变量的初始化次序优于任何方法,甚至在构造方法的前面。对于static变量也是同样,
 若是变量是原始类型,那么它获得一个标准的原始类型的初始值,
 若是是一个对象的引用,除非你建立了一个新的对象给这个引用,不然就是null。
 static变量在须要的时候才会初始化,而且在这个类的构造函数和全部其余普通变量以前调用,static以后就再也不进行初始化了,
 static变量在类初始化时(注意不是实例),就必须分配内存空间,
 static变量单独划分一块存储空间。

 java类首次装入时,会对静态成员变量或方法进行一次初始化,
 先初始化父类的静态代码-->初始化子类的静态代码-->
 (建立使历史,若是不建立实例,则后面的不执行)初始化父类的非静态代码-->初始化父类的构造
     -->初始化子类的非静态代码-->初始化子类的构造

 类只有在使用new调用建立的时候才会被java类装载器装入。

【final方法为什么会高效】:优化

final方法会在编译的过程当中利用内嵌机制进行inline优化。
inline优化是指:在编译的时候直接调用函数代码替换,而不是在运行时调用函数。
inline须要在编译的时候就知道最后要用哪一个函数,    
显然,非final是不行的。
非final方法可能在子类中被重写,因为可能出现多态的状况,编译器在编译阶段
并不能肯定未来调用方法的对象的真正类型,也就没法肯定到底调用哪一个方法。

【什么是多态】:线程

按字面的意思是“多种状态”。在面向对象语言中,接口的多种不一样的实现方式即为多态。
简单的说,就是一句话:容许将子类类型的指针赋值给父类类型的指针。

【非final方法为何会出现多态】:设计

显然,若是派生出一个子类,覆盖非final方法,就会出现2个这样的方法可供调用,这就是多态。

【final变量的变与不变】:指针

有人说final变量在赋值后就不可变,
那么这个不变到底指的是什么呢?
这个不变指的是引用,是地址,而所引用的对象的内容仍然是可变的。
就是说,这个final变量永远指向某个对象,是一个常量指针,而不是指向常量的指针。

===========================================================================================code

【final关键字的具体应用】:对象

【final+变量】:
    在实际应用中,这种形式是很是少见的。
    好比logger是能够的,可是貌似并非很是实用,或许用户仍然但愿经过setter来改变logger变量。
【static+final+变量】:
    常量。常用。
【final+方法】:
    JDK中经常使用,可是本身并未经常使用。
【final+类】:
    helper类常用。
【final用于匿名内部类的参数传递】:
    在多线程测试时,常用。
【final用于方法的参数】:
    并不经常使用。
相关文章
相关标签/搜索