Java并发编程 III - 让共享数据只读(final关键字)

Java并发编程 I - 并发问题的源头
Java并发编程 II - 没有共享就没有伤害(ThreadLoacl)
Java并发编程 III - 让共享数据只读(final关键字)
Java并发编程 IV - volatile关键字与Atomic类
Java并发编程 V - 并发的万能钥匙synchronized
Java并发编程 VI - 线程生命周期与线程间的协作
Java并发编程 VII - Lock

final关键字基本用法


修饰类

final修饰的类:类不能被继承;所有成员方法都会被隐式地指定为final方法。

常见的String、Long、Integer等包装类都是final修饰的类。


修饰方法

final修饰的方法:子类无法重写该方法。


修饰变量

final修饰的变量:基本数据类型一旦赋值便无法变更;引用类型一旦初始化便无法指向其他对象。

注意:引用类型被修饰成final后,其内部的变量依旧是普通变量。


final变量 与 普通变量 区别

		String str = "aabb";

        final String a1 = "aa";
        String test1 = a1 + "bb";
        System.out.println((str == test1)); //输出 -> true

        String a2 = "aa";
        String test2 = a2 + "bb";
        System.out.println((str == test2)); //输出 -> false

        final String a3;
        a3 = "aa";
        String test3 = a3 + "bb";
        System.out.println((str == test3)); //输出 -> false

        /* 编译后的class
        String str = "aabb";
        String a1 = "aa";
        String test1 = "aabb";
        System.out.println(str == test1);

        String a2 = "aa";
        String test2 = a2 + "bb";
        System.out.println(str == test2);

        String a3 = "aa";
        String test3 = a3 + "bb";
        System.out.println(str == test3);
         */

当final修饰基本数据类型或String类型的时候,在编译期间能确切知道final成员变量的值的情况下,编译器会进行优化,直接把引用了final成员变量的地方替换成实际值。

例如test1的情况,在编译期就直接把拼接给做好。


final 与 static 区别

        public static class TT{
            public static double a = Math.random();
            public final double b = Math.random();
        }

        TT t1 = new TT();
        //输出 -> t1 static=0.35115282629834366 final=0.13670857341151854
        System.out.println("t1 static=" + t1.a + " final=" + t1.b);

        TT t2 = new TT();
        //输出 -> t2 static=0.35115282629834366 final=0.12446163355351891
        System.out.println("t2 static=" + t2.a + " final=" + t2.b);

static变量被所有的对象所共享在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
final是保证变量不可变而已,并不会所有的对象共享。


final关键字作用

final修饰变量能够提供性能

在编译期,编译器会对final修饰的变量进行优化。

	//TT.java
	public class TT{
        private final int j = 100;

        public void t(){
            if (j < 100){
                System.out.println("aaaaaaa");
            }else {
                System.out.println("bbbbbbb");
            }
        }
    }

	//TT.class
	//final修饰的变量j参与的判断语句直接被简化
	public class TT {
        private final int j = 100;

        public TT() {
        }

        public void t() {
          System.out.println("bbbbbbb");
        }
    }

final修饰的变量是线程安全的

由于final的不可变机制。final修饰的变量无需担心出现并发问题。
但是需要注意,final修饰实例对象时只能保证该对象线程安全,并不能保证该对象内的非final变量也是线程安全,因为内部的这些变量还是可以被修改的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值