内部クラスのデッドロック

2916 ワード

最近2日間内部クラスを研究して、小さいテストを書く時1つの問題を発見して、比較的に面白くて、内部クラスの中でデッドロックと呼ぶことができて、外部クラスと内部クラスがすべて初期化することができません.

package Thinking;

public class InnerClass{
	Inner inner;
	public class Inner{
		int i;
		String name;
		public Inner(int i,String name){
			this.i=i;
			this.name=name;
		}
		public int geti(){
			return i;
		}
		public String getname(){
			return name;
		}
	}
	public InnerClass(Inner inner){
                  if(inner!=null)
		   this.inner=inner;
	}
	
	public static void main(String[] args){
	}
}

外部クラスには内部クラスドメインが定義され、それに対応する構造方法が再定義され、内部クラスドメインをコンストラクタのパラメータとして使用します.外部クラスオブジェクトを持つ前に内部クラスオブジェクトを作成することはできないため、外部クラスオブジェクトは先に作成する必要がありますが、外部クラスのコンストラクタには内部クラスオブジェクトが含まれているため、デッドロックが発生します.インスタンスオブジェクトを作成できません.
もちろん、この問題は解決策がないわけではありません.main関数でInnerの空のアプリケーションオブジェクトを定義してから、外部クラスの構造関数を代用することができますが、この方法は無効な初期化と呼ばれています.個人的には、無効な初期化後に内部クラスオブジェクトを作成し、最後に内部クラスに付与する2つの方法があると思います.2つ目はsetメソッドを追加し、内部クラスドメインを設定することです.
方法1:

package Thinking;

public class InnerClass{
	Inner inner;

	public class Inner{
		int i;
		String name;
		public Inner(int i,String name){
			this.i=i;
			this.name=name;
		}
		public int geti(){
			return i;
		}
		public String getname(){
			return name;
		}
	}

	public InnerClass(Inner inner){
		if(inner!=null)
		this.inner=inner;
	}
	
	public static void main(String[] args){
		Inner a=null;
		InnerClass b=new InnerClass(a);
		System.out.println(b.inner);
		b.inner=b.new Inner(1,"hust");
		System.out.println(b.inner);
	}
}
//output
null
Thinking.InnerClass$Inner@4f1d0d

外部ファイルアクセスの場合、この方法ではinnerのアクセス権が高くなります.
方法2:

package Thinking;

public class InnerClass{
	Inner inner;
	
	public class Inner{
		int i;
		String name;
		public Inner(int i,String name){
			this.i=i;
			this.name=name;
		}
		public int geti(){
			return i;
		}
		public String getname(){
			return name;
		}
	}
	
	public InnerClass(Inner inner){
		if(inner!=null)
		this.inner=inner;
	}
	
	public void setInner(Inner inner){
		this.inner=inner;	}
	
	public static void main(String[] args){
		Inner a=null;
		InnerClass b=new InnerClass(a);
		System.out.println(b.inner);
		b.setInner(b.new Inner(1,"hust"));
		System.out.println(b.inner);
	}
}
//output
null
Thinking.InnerClass$Inner@4f1d0d

この方法はinnerのアクセス権限がprivateであることを保証し、innerを保護することができる.