不変性とは(不変)
オブジェクトの作成後にオブジェクトの状態を変更できない場合、オブジェクトは不変です。
不変性のあるオブジェクトはスレッドセーフである必要があり、追加の安全対策を講じる必要はありません。また、スレッドセーフも保証されます。
コードデモ
/**
* @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);
}
}
プログラムの出力から、グローバル変数は共有リソース領域であることがわかります。