一、今日学习内容:final关键字。

1. final变量

             凡是对成员变量或者本地变量(在方法中的或者代码块中的变量称为本地变量)声明为final的都叫作final变量。final变量经常和static关键字一起使用,作为常量。用final关键字修饰的变量,只能进行一次赋值操作,并且在生存期内不可以改变它的值。
不过在针对基本类型和引用类型时,final关键字的效果存在细微差别。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
    final double value2;
    value2 = 2.0;
    final Value value3 = new Value(1);
    value3.v = 4;
  }
}

           上面的例子中,main方法中被final修饰的数据,在给value1赋初始值之后,我们无法再对value1的值进行修改,final关键字起到了常量的作用。从value2我们可以看到,final修饰的变量可以不在声明时赋值,即可以先声明,后赋值。value3时一个引用变量,这里我们可以看到final修饰引用变量时,只是限定了引用变量的引用不可改变,即不能将value3再次引用另一个Value对象,但是引用的对象的值是可以改变的。
另一方面,我们看到了用final修饰成员变量时的细微差别,因为final修饰的数据的值是不可改变的,所以我们必须确保在使用前就已经对成员变量赋值了。因此对于final修饰的成员变量,我们有且只有两个地方可以给它赋值,一个是声明该成员时赋值,另一个是在构造方法中赋值,在这两个地方我们必须给它们赋初始值。
最后我们需要注意的一点是,同时使用static和final修饰的成员在内存中只占据一段不能改变的存储空间。

2. final方法参数

             如果变量是我们自己创建的,那么使用final修饰表示我们只会给它赋值一次且不会改变变量的值。那么如果变量是作为参数传入的,我们怎么保证它的值不会改变呢?这就用到了final的第二种用法,即在我们编写方法时,可以在参数前面添加final关键字,它表示在整个方法中,我们不会(实际上是不能)改变参数的值:

1
2
3
4
5
6
7
8
public class FinalTest {
  /* ... */
  public void finalFunc(final int i, final Value value) {
    // i = 5; 不能改变i的值
    // v = new Value(); 不能改变v的值
    value.v = 5; // 可以改变引用对象的值
  }
}

3. final方法

              final也可以声明方法。方法前面加上final关键字,代表这个方法不可以被子类的方法重写。如果你认为一个方法的功能已经足够完整了,子类中不需要改变的话,你可以声明此方法为final。final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。关于private和final关键字还有一点联系,这就是类中所有的private方法都隐式地指定为是final的,由于无法在类外使用private方法,所以也就无法覆盖它。下面是final方法的例子:

1
2
3
4
5
6
7
8
9
10
11
class PersonalLoan{
  public final String getName(){
    return "personal loan";
  }
}
class CheapPersonalLoan extends PersonalLoan{
  @Override
  public final String getName(){
    return "cheap personal loan"; //compilation error: overridden method is final
  }
}

4. final类

            使用final来修饰的类叫作final类。final类通常功能是完整的,它们不能被继承。Java中有许多类是final的,譬如String, Interger以及其他包装类。下面是final类的实例:

1
2
3
final class PersonalLoan{
 }
 class CheapPersonalLoan extends PersonalLoan{ //compilation error: cannot inherit from final class

5. final关键字的好处

  1. final关键字提高了性能。JVM和Java应用都会缓存final变量。
  2. final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
  3. 使用final关键字,JVM会对方法、变量及类进行优化。

       创建不可变类要使用final关键字。不可变类是指它的对象一旦被创建了就不能被更改了。String是不可变类的代表。不可变类有很多好处,譬如它们的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销等等。

二、遇到的问题:

 final关键字的用法不清楚。

三、明日学习计划:

学习abstract关键字,继续阅读《大道至简》。

posted on 2020-07-24 22:08  白日梦想家~  阅读(100)  评论(0编辑  收藏  举报