JAvaの基礎——staticの深い理解

3206 ワード

JAvaのstaticでは、メンバー変数、メソッド、クラス、コードブロックを修飾できます.
1.static変数
クラスメンバー変数を静的に分類するかどうかによって2つに分けることができます.1つはstaticによって修飾された変数で、静的変数またはクラス変数と呼ばれます.もう1つはstaticによって修飾されていない変数で、インスタンス変数と呼ばれます.両者の違いは、静的変数がメモリに1つしかコピーされていない(メモリを節約する)場合、JVMは静的メモリを1回だけ割り当て、クラスをロードする過程で静的変数のメモリ割り当てを完了し、クラス名で直接アクセス(便利)することができ、もちろんオブジェクトでアクセスすることもできます(ただし、これは推奨されません).インスタンス変数の場合、インスタンスを作成するたびに、インスタンス変数にメモリが割り当てられます.インスタンス変数は、メモリに複数のコピーがあり、互いに影響しません(柔軟です).
2、静的方法
静的メソッドはクラス名で直接呼び出すことができ、任意のインスタンスも呼び出すことができるため、静的メソッドではthisとsuperキーを使用することはできません.所属するクラスのインスタンス変数とインスタンスメソッド(staticを持たないメンバー変数とメンバーメソッド)に直接アクセスすることはできません.所属するクラスの静的メンバー変数とメンバーメソッドにのみアクセスできます.インスタンスメンバーが特定のオブジェクトに関連付けられているためです.staticメソッドは任意のインスタンスとは独立しているため、抽象的なabstractではなく、staticメソッドを実装する必要があります.
3.static修飾クラス
一般的な静的内部クラスはstaticで修飾できます(java内部クラスは、通常の内部クラス、静的内部クラス、ローカル内部クラス、匿名内部クラスの4つに分けられます).外部クラスのstaticメンバーのみにアクセスでき、外部クラスのインスタンス変数とインスタンスメソッドに直接アクセスできません.
4.static文ブロック
複数あり、場所は任意に置くことができ、それはいかなる方法の体内にもなく、JVMがクラスをロードするときにこれらの静的なコードブロックを実行します.(1)1つのクラスに複数のstatic{}がある場合、static{}の定義順に、行き先から実行する.(2)static{}文ブロックの内容を先に実行してから呼び出し文を実行する.
	public class A {
	
	    public static void main(String args[]){
	        System.out.println(5);
	    }
	 	static{
	        System.out.println(1);
	    }
	    static {
	        System.out.println(2);
	    }
	    static {
	        System.out.println(3);
	    }
	    static {
	        System.out.println(4);
	    }
	}//     1 2 3 4 5 

(3)静的変数が定義時に初期値(static int X=100など)を付与した場合、付与操作もクラスロード時に完了し、1つのクラスにstatic{}とstatic変数がある場合、同様に「先に定義して実行する」の原則に従う.
public class A {
		public static int x = 10;
		static{
			System.out.println(x);
			x = 20;
			System.out.println(x);
		}
		
		public static void main(String args[]){
	       int y = A.x;
	    }
	}//   10  20

(4)staticによるクラスのロード順序の理解
(4.1)クラスAでmain()を実行する場合は,まずA,Bを初期化する前に,まずBをロードする.
public class A   {
	static{
		System.out.println("Static A");
	}
	public A(){
		System.out.println("constructor A");
	}
	public static void main(String args[]){
	     new B(); 
	}
}
class B {
	static{
		System.out.println("Static B");
	}
	public B(){
		System.out.println("constructor B");
	}
}

実行結果:
Static AStatic Bconstructor B
(4.2)クラスAがロードされる前に親をロードする
public class A extends B  {
	static{
		System.out.println("Static A");
	}
	public A(){
		System.out.println("constructor A");
	}
	public static void main(String args[]){
	     new A(); 
	}
}
class B {
	static{
		System.out.println("Static B");
	}
	public B(){
		System.out.println("constructor B");
	}
}

結果:
Static BStatic Aconstructor Bconstructor A(4.2)静的フィールドXを直接定義するクラスのみが初期化される
public class A  extends B{
	static{
		System.out.println("Static A");
	}
	public A(){
		System.out.println("constructor A");
	}
	
}
class B {
	public static int x = 10;
	static{
		System.out.println("Static B");
	}
	public B(){
		System.out.println("constructor B");
	}
}
public class C {
	public static void main(String args[]){
	     System.out.println(A.x);
	}
}
結果:
Static B 10