• 多线程学习笔记-2.final关键字和不变性


    1. 什么是不变性

    在这里插入图片描述

    • 不可变的对象,演示其他类无法修改这个对象,public也不行
    • 案例演示
      在这里插入图片描述

    2. final的作用

    在这里插入图片描述

    3. 3种用途:修饰变量、方法、类

    3.1 修饰变量

    在这里插入图片描述

    public class Person {
        final int age = 18;
        final String name = alice;
        String bag = "computer";
        public static void main(String[] args) {
            final Person person = new Person();
        	person.bag = "book";   // 可以修改类的内容
    //      person = new Person(); // 不能重新引用
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    在这里插入图片描述

    1. 类中的final变量属性

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2. 类中的staic final属性

    在这里插入图片描述

    /**
     * 描述:     演示final变量
     */
    public class FinalVariableDemo {
    	// 1.可以直接赋值
        private static final int a;
    	// 2.或是在静态代码块中赋值
    //    static { 
    //        a = 7;
    //    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    方法中的final变量

    在这里插入图片描述

    /**
     * 描述:     演示final变量
     */
    public class FinalVariableDemo {
    //    void testFinal() {
    //       final int b = 7;
    //       int c = b;// 确保b使用时,是有赋值的
    //    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.2 修饰方法

    在这里插入图片描述
    在这里插入图片描述

    • 子类理论上是可以定义与父类相同的静态方法,但是属于各自类,没有继承关系

    3.3 修饰类

    在这里插入图片描述

    4. 注意点

    在这里插入图片描述

    5. 不变性和final的关系

    5.1 如何确保类不可变

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    5.2 栈封闭

    在这里插入图片描述

    package immutable;
    
    /**
     * 描述:     演示栈封闭的两种情况,基本变量和对象 先演示线程争抢带来错误结果,然后把变量放到方法内,情况就变了
     */
    public class StackConfinement implements Runnable {
    
        int index = 0;
    
        public void inThread() {
            // 方法内的变量,不共享,是安全的
            int neverGoOut = 0;
    //        synchronized (this) {
                for (int i = 0; i < 10000; i++) {
                    neverGoOut++;
                }
    //        }
    
            System.out.println("栈内保护的数字是线程安全的:" + neverGoOut);
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                index++;
            }
            inThread();
        }
    
        public static void main(String[] args) throws InterruptedException {
            StackConfinement r1 = new StackConfinement();
            Thread thread1 = new Thread(r1);
            Thread thread2 = new Thread(r1);
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println(r1.index);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述

    6. 常见面试题

    在这里插入图片描述
    示例1:
    在这里插入图片描述

    • 因b被final修饰,故,是不变的常量,编译期就确定的,这样,c能发现b,直接计算出字符串值wukong2,发现常量池中有,就直接指向a指向的常量,因此,地址一样
    • 但,d不同,在编译器无法识别,只有在运行时确定,e会在运行时在堆上创建一个指向wokong2的引用,因此,地址不同
      示例2:
      在这里插入图片描述
    • 获取方法的值,编译器不会做优化,只有在运行期才能拿到
  • 相关阅读:
    【计算机网络】UDP/TCP协议
    无胁科技-TVD每日漏洞情报-2022-10-25
    Python基础复习-面向对象的编程
    React实现地图搜索
    详细剖析多线程4----锁策略(八股文/面试常考)
    安装淘宝镜像cnpm
    MySQL查询语句有代码示例
    Swift学习内容精选(一)
    消息中间件-kafka实战-第一章-介绍
    软件架构设计 C/S与B/S架构的区别
  • 原文地址:https://blog.csdn.net/xingzhes_/article/details/126011797