java基础-final用法

1、final关键字的含义

    final在Java中能够声明成员变量、方法、类以及本地变量。一旦你将引用声明final,你将“不能改变”这个引用了,编译器会检查代码,若是你试图将变量再次初始化的话,编译器会报编译错误。java

2、修饰数据

    在编写程序时,咱们常常须要说明一个数据是不可变的,咱们成为常量。在java中,用final关键字修饰的变量,只能进行一次赋值操做,而且在生存期内不能够改变它的值。更重要的是,final会告诉编译器,这个数据是不会修改的,那么编译器就可能会在编译时期就对该数据进行替换甚至执行计算,这样能够对咱们的程序起到一点优化。不过在针对基本类型和引用类型时,final关键字的效果存在细微差异。咱们来看下面的例子:程序员

class Value {
    int v;
    public Value(int v) {
        this.v = v;
    }
}

public class finaltest {
    final int f1 = 1;
    final int f2;
    public finaltest() {
        f2 = 2;
    }
    public static void main(String[] args) {
        final int value1 = 1;
//        value1 = 4;
        System.out.println(value1);
        final double value2;
        value2 = 2.0;
        System.out.println(value2);
        final Value value3 = new Value(1);
        System.out.println(value3.v);
        value3.v = 4;
        System.out.println(value3.v);
    }
}

    上面的例子中,咱们先来看一下main方法中的几个final修饰的数据,在给value1赋初始值以后,咱们没法再对value1的值进行修改,final关键字起到了常量的做用。从value2咱们能够看到,final修饰的变量能够不在声明时赋值,便可以先声明,后赋值。value3时一个引用变量,这里咱们能够看到final修饰引用变量时,只是限定了引用变量的引用不可改变,即不能将value3再次引用另外一个Value对象,可是引用的对象的值是能够改变的,从内存模型中咱们看的更加清晰:性能

    上图中,final修饰的值用粗线条的边框表示它的值是不可改变的,咱们知道引用变量的值其实是它所引用的对象的地址,也就是说该地址的值是不可改变的,从而说明了为何引用变量不能够改变引用对象。而实际引用的对象其实是不受final关键字的影响的,因此它的值是能够改变的。优化

    另外一方面,咱们看到了用final修饰成员变量时的细微差异,由于final修饰的数据的值是不可改变的,因此咱们必须确保在使用前就已经对成员变量赋值了。所以对于final修饰的成员变量,咱们有且只有两个地方能够给它赋值,一个是声明该成员时赋值,另外一个是在构造方法中赋值,在这两个地方咱们必须给它们赋初始值。this

最后咱们须要注意的一点是,同时使用static和final修饰的成员在内存中只占据一段不能改变的存储空间spa

3、修饰方法参数

    前面咱们能够看到,若是变量是咱们本身建立的,那么使用final修饰表示咱们只会给它赋值一次且不会改变变量的值。那么若是变量是做为参数传入的,咱们怎么保证它的值不会改变呢?这就用到了final的用法,即在咱们编写方法时,能够在参数前面添加final关键字,它表示在整个方法中,咱们不会(其实是不能)改变参数的值:设计

public class finaltest {
    public void finalFunc(final int i, final Value value) {
        // i = 5; 不能改变i的值
        // v = new Value(); 不能改变v的值
        value.v = 5; // 能够改变引用对象的值
    }
}

4、修饰方法

    第三种方式,即用final关键字修饰方法,它表示该方法不能被重写。这种使用方式主要是从设计的角度考虑,即明确告诉其余可能会继承该类的程序员,不但愿他们去重写这个方法。这种方式咱们很容易理解,然而,关于private和final关键字还有一点联系,这就是类中全部的private方法都隐式地指定为是final的,因为没法在类外使用private方法,因此也就没法重写它。code

5、修饰类

    了解了final关键字的其余用法,咱们很容易能够想到使用final关键字修饰类的做用,那就是用final修饰的类是没法被继承的。对象

6、总结

    final关键字是咱们常用的关键字之一,它的用法有不少,可是并非每一种用法都值得咱们去普遍使用。对于第四和第五用法,咱们却甚少使用。这不是没有道理的,从final的设计来说,这两种用法甚至能够说是鸡肋,由于对于开发人员来说,若是咱们写的类被继承的越多,就说明咱们写的类越有价值,越成功。即便是从设计的角度来说,也没有必要将一个类设计为不可继承的。Java标准库就是一个很好的反例,特别是Java 1.0/1.1中Vector类被如此普遍的运用,若是全部的方法均未被指定为final的话,它可能会更加有用。如此有用的类,咱们很容易想到去继承和重写他们,然而,因为final的做用,致使咱们对Vector类的扩展受到了一些阻碍,致使了Vector并无彻底发挥它应有的所有价值。继承

它的主要用法有如下四种:

  • 修饰数据:包括成员变量和局部变量,该变量只能被赋值一次且它的值没法被改变。对于成员变量来说,咱们必须在声明时或者构造方法中对它赋值;
  • 修饰方法参数:表示在变量的生存期中它的值不能被改变;
  • 修饰方法:表示该方法没法被重写;
  • 修饰类:表示该类没法被继承。

7、相关final的重要知识点

  1. final关键字能够用于成员变量、本地变量、方法以及类。
  2. final成员变量必须在声明的时候初始化或者在构造器中初始化,不然就会报编译错误。
  3. 你不可以对final变量再次赋值。
  4. 本地变量必须在声明时赋值。
  5. 在匿名类中全部变量都必须是final变量。
  6. final方法不能被重写。
  7. final类不能被继承。
  8. final关键字不一样于finally关键字,后者用于异常处理。
  9. final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收以前被JVM调用的方法。
  10. 接口中声明的全部变量自己是final的。
  11. final和abstract这两个关键字是反相关的,final类就不多是abstract的。
  12. final方法在编译阶段绑定,称为静态绑定(static binding)。
  13. 没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么作的话,编译器会报错“final变量(变量名)须要进行初始化”。
  14. 将类、方法、变量声明为final可以提升性能,这样JVM就有机会进行估计,而后优化。
相关文章
相关标签/搜索