Java 之 final 关键字

昨天在群里突然看到一个问题:final 有什么作用?有什么好处?线程安全吗?

虽然平时也经常使用到final关键字,但是想说出所以然来,好像还挺困难。重新温故知新一下。

先看了Java 编程思想:
final修饰变量
final修饰的变量称为常量。如果在编译器就永不改变的称为编译时常量。还有一种是运行时被初始化,但不会被改变。

编译时常量,只能是原始类型变量,如:

private final int valueOne = 9;
private static final int VALUE_TWO = 99;
public static final int VALUE_THREE = 39;

被final修饰的成员变量,也可以被其他关键字修饰,一般static final 一起修饰时变量名称全部大写,单词间用下划线分隔。

public class FinalData {
   private static Random random = new Random(47);
   private final int i4 = random.nextInt(20);
   static final int INT_5 = random.nextInt(20);
}

final修饰的变量也可以是运行时才初始化,每次运行均被初始化为一个随机数
但是如果还有static修饰,则根据static关键字的作用,该变量只会被初始化一次

Final fd1 = new Final();
Final fd2 = new Final();

两次实例化对象,i4是很大可能不一样的,但INT_5是一样的

final也可以修饰引用变量,修饰引用变量时,该对象的是不能被在指向新的引用对象,但是其引用的对象内容是可以发生改变的:

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

public class FinalData {
    private final Value v2 = new Value(22);
    private static final Value VAL_3 = new Value(33); 
}

是可以执行如下操作的:

FinalData fd = new FinalData();
fd.v2.i++;
FinalData .VAL_3.i++;

但不可以执行如下操作:

FinalData fd = new FinalData();
fd.v2 = new Value();//编译失败

即final修饰引用变量对象不可以在此被赋值为其他对象,但是该对象的内部属性值可以被修改

还有一种比较常见的是数组:

public class FinalData {
    private final int[] a = {1,2,3,4,5,6};
}

数组内部的值也是可以发生改变的:

FinalData fd = new FinalData();
fd.a[4]++;

final修饰方法
如果方法被final修饰,则该方法不能被子类Override,但是可以被Overload

public class FinalMethod {
    public final void test() {
    }
    public final void test(String name) {
    }
}

public class FinalMethodSon extends FinalMethod {
    @Override
    public final void test() {
    } //编译失败
}

所有的private方法都是隐式的指定为final。private方法子类也无法Override,但没有必要再加上final关键字,没有额外的意义

final修饰类
final修饰类即表示这个类不能被继承,final修饰的类,其内方法都会被隐式地指定为final,其内的变量可以是final也可以不是final

浅析Java中的final关键字博客中有个例子很不错:

public class Test {
    public static void main(String[] args) {
        String a = "hello2";
        final String b = "hello";
        String d = "hello";
        String c = b + 2;
        String e = d + 2;
        System.out.println(a == c);//true
        System.out.println(a == e);//false
    }
}

final修饰方法参数和在匿名内部类中使用,可以参考《浅析Java中的final关键字》和《Java内部类详解》

final 线程安全 最好的例子是String类,String类是一个不可变类,后续再整理一个String 不可变性相关的

简单总结了一个思维导图:
这里写图片描述

参考的博客:
深入理解Java中的final关键字:http://www.importnew.com/7553.html
浅析Java中的final关键字:http://www.cnblogs.com/dolphin0520/p/3736238.html
Java内部类详解:http://www.cnblogs.com/dolphin0520/p/3811445.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值