06-JUC-不変

不変性とは(不変)

オブジェクトの作成後にオブジェクトの状態を変更できない場合、オブジェクトは不変です。
不変性のあるオブジェクトはスレッドセーフである必要があり、追加の安全対策を講じる必要はありません。また、スレッドセーフも保証されます。

コードデモ

/**
 * @Classname Person
 * @Description  不可变对象,演示其他类无法修改这个对象。
 * @Date 2021/2/18 17:12
 * @Created by YoungLiu
 */
public class Person {
    
    

    //加了final
     final int age =18;
     final String name ="Alice";

    public static void main(String[] args) {
    
    
        Person person = new Person();
        //这里会报错,因为都是final修饰的,不可变。
        person.age=19;
    }
}

最後のキーワードの役割

ここに画像の説明を挿入
ここに画像の説明を挿入

最終的に変更された変数

finalによって変更された変数は、値を変更できないことを意味します。変数がオブジェクトの場合、オブジェクトの参照は変更できませんが、オブジェクト自体のコンテンツは変更できます。

public class Person {
    
    

    //加了final
     final int age =18;
     final String name ="Alice";
	  String bag ="this is the content of object.";
    public static void main(String[] args) {
    
    
       final Person person = new Person();
       //这里会报错,因为被final的对象变量,对象的引用不能改变。
        person = new Person();
        //对象的内容可以改变
          person.bag="The object content could be change.";
    }
}

ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入

/**
 * @Classname FinalVariableDemo
 * @Description 演示final变量的赋值时机,final修饰的变量必须选择一种赋值时机
 * @Date 2021/2/18 17:30
 * @Created by YoungLiu
 */
public class FinalVariableDemo {
    
    
    //第一种赋值时机
//    private final int  a =6;
    private final int a ;

    //第二种赋值时机
//    public FinalVariableDemo(int a) {
    
    
//        this.a = a;
//    }

    //第三种赋值情况
    {
    
    
        a= 6;
    }
}

ここに画像の説明を挿入

/**
 * @Classname FinalVariableDemo2
 * @Description 演示final static变量的赋值时机,
 * @Date 2021/2/18 17:30
 * @Created by YoungLiu
 */
public class FinalVariableDemo2 {
    
    

    //第一种赋值时机
//    private static final int a = 3 ;
    private static final int a ;



    //第二种赋值时机
    static{
    
    
        a= 6;
    }
}

ここに画像の説明を挿入

public class FinalVariableDemo2 {
    
    



    void testFinal(){
    
    
        //对于local final 变量 在使用前必须先赋值
        final int b;
    }
    
}

最終修正方法

ここに画像の説明を挿入


/**
 * @Classname FinalMethodDemo
 * @Description  演示被final修饰的方法
 * @Date 2021/2/18 20:00
 * @Created by YoungLiu
 */
public class FinalMethodDemo {
    
    

    public void drink(){
    
    

    }

    public final void eat(){
    
    

    }

    public static void sleep(){
    
    

    }
}
class SubClass extends FinalMethodDemo{
    
    
    @Override
    public void drink() {
    
    
        super.drink();
    }

    //不能重写父类的final 方法
//    public void eat(){
    
    
//
//    }

    //不能重写父类的static方法,但可以写成一模一样。
//    public static void sleep(){
    
    
//
//    }
}

最終的に変更されたクラス

特定のクラス、メソッド、変数が定義された後も変更されないことがわかっている場合は、finalを使用して変更できます。

ここに画像の説明を挿入

不変性と最終的な関係

ここに画像の説明を挿入

ここに画像の説明を挿入

スタックが閉じています

ここに画像の説明を挿入

コードデモ

/**
 * @Classname StackConfinement
 * @Description 演示栈封闭的两种情况:基本变量和对象
 * 1.先演示线程争抢带来错误结果,然后把变量放到方法内,情况就变了。
 * @Date 2021/2/18 20:19
 * @Created by YoungLiu
 */
public class StackConfinement implements Runnable{
    
    

    //全局变量被两个线程共享,会出现线程安全的问题;
    int index = 0;

    public void inThread(){
    
    
        //每个线程都有一个nerverGoOut变量
        int neverGoOut = 0;
        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 t1 = new Thread(r1);
        Thread t2 = new Thread(r1); 
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(r1.index);
    }
}

プログラムの出力から、グローバル変数は共有リソース領域であることがわかります。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_41729287/article/details/113850041