文章目录

  • final关键字基本用法
  • 修饰类
  • 修饰方法
  • 修饰变量
  • final变量 与 普通变量 区别
  • final 与 static 区别
  • final关键字作用
  • final修饰变量能够提供性能
  • final修饰的变量是线程安全的

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变量也是线程安全,因为内部的这些变量还是可以被修改的。