[面接準備]Mutable,Immutable,final

5600 ワード

MutableとImmutableは何ですか?それぞれどんな特徴がありますか?
Immutableとは、オブジェクトが最初に作成された時点を除き、オブジェクト内部の状態が全く変化しないことを意味します.特に同期がなくても常にthread safeなので、どのスレッドでも思う存分安全に使用できます.代表的な不変オブジェクトはStringです.
クラスを一定に保つには、次のルールに従います.
1.オブジェクトのステータスを変更する方法はありません.
2.すべてのクラス変数をprivateとfinal:finalキーワードとして宣言すると、変数の再割り当てが阻止され、privateは外部から直接変数にアクセスします.
3.内部可変オブジェクトへのアクセスを禁止します.クラスに可変オブジェクトを参照するフィールドがある場合、外部はそのオブジェクトの参照を取得できません.参照が変更される可能性がある場合は、防御レプリケーションを使用して転送します.
//Game.class
public class Game {
	private final List<String> list = new ArrayList<>();
	...
	public List<String> getList() { 
    	return Collections.unmodifiableList(list); 
    }
  • クラスの拡張は許可されていません.継承を阻止する方法には、クラスを最終的に宣言する方法がありますが、静的ファクトリを提供する方法もあります.(静的ファクトリは、作成者をプライベートとして保持し、パブリック静的ファクトリメソッドを提供します.パブリックまたは保護された作成者がいないため、他のパッケージからクラスを拡張することはできません.)
  • public class Complex {
    	private final double re;
    	private final double im;
    
    	private Complex(double re, double im) {
    
    		this.re = re;this.im = im;
    	}
    
    	public static Complex valueOf(doulble re, double im) {
    		return new Complex(re, im);
    	}
    }
    メリットは
  • スレッドは安全で、同期を必要とせずにマルチスレッド環境で安全に使用できます.
  • のインスタンスを1回作成すると、リサイクルできます.つまり、オブジェクトの作成数を減らすことができます.
  • public static final Complex ZERO = new Complex(0,0);
    欠点は
  • の値が異なる場合は、独立したオブジェクトにする必要があります.価格の種類が多ければ、これらを作るのに大きな費用がかかります.価格の種類が多ければ、これらを作るのに大きな費用がかかります.しかし、百万ビットのBigIntegerはビットを交換します.flibBitメソッドは、新しいBigIntegerインスタンスを作成するときに、ウォーボンの1ビットとは異なる場合でも、100万ビットのインスタンスを作成します.この演算はBigIntegerの大きさに比例し,時間と空間を占有する.BitSetもBigIntegerのように任意の長さのビットシーケンスを表すが、BigIntegerとは異なり「可変」である.BigSetクラスは、一定時間内に必要なビットを1つだけ変更できる方法を提供する.
  • この効果javaアイテム17の変更の可能性を最小限に抑えるには、記事を参照してください。
    Javaの集合.API(unmodifiableListなど)を使用して、リストなどのセットを変更できません.では、このAPIを使って不変性を実現できますか?
    Collections.unmodifiableList()のようなメソッドはRead-onlyにしか使用できません.add()やaddAll()などのメソッドの変更を呼び出すと異常になります.
    通常、クラスの内部に可変オブジェクトのセットがある場合、変更が参照されるため、可変オブジェクトに直接渡すのではなく、unmodifiableListによって防御的なコピーが伝達されます.コピーしたリストは変更できません.しかし、本来の自分への修正は止められない.
    
    public class Test {
    
    	public static void main(String []args) {
    
    		List<String> list = new ArrayList<String>();
    		list.add("a");
            list.add("b");
    		list.add("c");
    		
            //수정을 못하도록 방어적 복사를 함.
    		List<String> unmodifiableList = Collections.unmodifiableList(list);
    
    		try {
    			unmodifiableList.add("d"); //수정을 못하기 때문에 exception 터짐
    			System.out.println("cannot be reached here");
    		} catch (UnsupportedOperationException e) {
    			System.out.println("Cannot modify unmodifiable list");//exception 터짐
    		}
    
    		list.add("d"); //원본자체에 대한 수정은 못막음!!!
    
    		System.out.println(unmodifiableList.get(3));//d로 수정된 값 출력
    	}
    }
    
    
    //출력 결과
    Cannot modify unmodifiable list
    d
    Immutableとは、オブジェクトが最初に作成された時点を除き、オブジェクト内部の状態が全く変化しないことを意味します.変更不可または変更不可のセキュリティコピーのリストは使用できませんが、元のリスト自体を変更できるため、不変性は達成できません.
    変数、メソッド、クラスにfinalキーワードを宣言する意味は何ですか?
  • finalクラス:継承できません.つまり、あなたは別の親になることはできません.
  • finalメソッド:オーバーシュートなし.
  • final変数:値の再割り当てをブロックします.
  • final fieldは無条件で変わらないのですか?
    finalは値を再割り当てできません.finalは英語の最終的な意味で、最後の意味のように初期に1回割り当てると最終的な値になります.つまり、変わらないのではなく、再分配を阻止する.
    final int num = 3; //할당 완료
    
    num = 4;//불가
    finalフィールドには、原語タイプ、参照タイプがあります.
    primitive typeでは、オブジェクトではなくテキスト値なので変わらない.
    ただし、referencetypeのfinalフィールドは変更されません.
    // reference type 필드
    //Game.class
    public class Game {
    	private final Car car = new Car();
    	...
    }
    
    //Main.class
    public void makeCar() {
    	car.setPosition(3);//상태 변경 가능
    }
    
    //Game.class
    public class Game {
    	private final List<String> playerNames = new ArrayList<>();
    	...
    }
    
    ...
    
    //Main.class
    player.getPlayerNames().add("one");// 상태 변경 가능
    player.getPlayerNames().add("two");// 상태 변경 가능
    
    上記のコードでは、reference type car、playerNameで内部状態を変更できます.したがってfinalは必ずしも変わらないとは限らない.
    リファレンス
    理想のJava
    Java不変オブジェクトとfinalを使用する理由
    finalは変わらないことを保証できますか?
    Java Unmodificable Collectionと不変の違い