JAVA高次(クラスローダ、反射、ダイナミックエージェント、設計モード)

7514 ワード

一、クラスローダ
≪クラスのロード|Load Class|emdw≫:プログラムがクラスを使用する場合、クラスがメモリにロードされていない場合、システムはロード、接続、初期化の3ステップでクラスの初期化を実現します.
1.クラス・ロードの3つのステップ
1.1ロード(クラス・ローダによる):
  • classファイルをメモリに読み込み、クラスオブジェクトを作成します(どのクラスも使用時にクラスオブジェクトを作成します).
  • 1.2リンク:
  • 内部構造が正しいことを確認します.
  • 準備:クラスの静的変数にコピーしてメモリを割り当て、デフォルト値を設定します.
  • 解析:クラスのバイナリデータのシンボル参照を直接参照
  • に置き換える.
    1.3初期化:
  • クラスの初期化:クラスは最後のフェーズをロードし、クラスにスーパークラスがある場合は初期化し、静的初期化器と静的初期化メンバー変数を実行します(デフォルト値のみを初期化したstatic変数がこのフェーズで付与され、メンバー変数も初期化されます).

  • 2.クラスのロードのタイミング:
  • クラスインスタンス
  • を作成する
  • 静的変数にアクセスし、静的変数に値を付与し、静的メソッド
  • を呼び出す.
  • は、そのサブクラス
  • を初期化する.
  • javaを使用する.exeコマンド実行クラス
  • 反射方式を使用して、クラスまたはインタフェースに対応するオブジェクト
  • を強制的に作成する.
    3.クラスローダ分類:
  • ルートクラスローダ:javaコアクラス(jdk/jre/rt.jarのclassファイル)
  • をロードする
  • 拡張クラスローダ:jreの拡張ディレクトリのjarパッケージのクラス(jdk/jre/lib/extディレクトリのclassファイル)
  • をロードします.
  • システムクラスローダ:javaコマンドからのclassファイルとclasspath環境変数で指定されたjarパッケージとクラスパスの下のclassファイル
  • をロードする
    二、反射
    1.定義:
  • classファイルオブジェクト、すなわちClassクラスのオブジェクト(クラスの対像ではない)を介して、クラスのメンバー変数、構築方法、メンバー方法
  • を使用する.
    2.Classクラス:
  • に対応するメンバー変数、構築方法、メンバーメソッドはすべてクラスです.(反射とは、Classクラスのオブジェクトを先に取得し、そのオブジェクトからそのメンバー変数/構築方法/メンバーメソッドを取得し、最後にそれぞれメンバー変数/構築方法/メンバーメソッドのオブジェクトから対応するメソッドを呼び出すことである)
  • .
  • Classクラスのオブジェクトを取得する方法
  • 法一:
    Person p=new Person();
    Class c=p.getClass();
    
  • 法二:
    Class c=Person.class;
    
  • 法三:
    Class c=Class.forName(    );
    
  • メソッド選択:
  • 法2は比較的簡単であるが、一般的に選択法3を開発している.法3パラメータの場合、文字列は比較的柔軟で、プロファイルのロードを通じて、メンテナンスが容易であるからだ.


  • 3.反射による構造方法
    Class c=Class.forName(Person   );// Person    
    
    //        ,   cons        
    	//          
    	Constructor[] cons=c.getConstructors();
    	//        (    )
    	Constructor[] cons=c.getDeclaredConstructors();
    	//      
    	for(Constructor con:cons)System.out.println(con)
    //        
    	//        (         )
    	Constructor con=c.getConstructor(String.class,int.class,String.class);//        (         )
    	//          (    )
    		Constructor con=c.getDeclaredConstructor(String.class);
    		//  java      
    		con.setAccessible(true);
    
    //           
    Object obj=con.newInstance(“   ”,12,“  ”);
    
    
    

    4.反射によるメンバー変数の取得と値の割り当て
    //         
    Class c=Class.forName(person   )
    Constructor con =c.getConstructor();
    Object obj=con.newInstance();
    
    //        
    	//           
    	Field[] fields=c.getFields();
    	//         (    )
    	Field[] fields=c.getDeclaredFields();
    //        
    	//           (       )
    	Field field=c.getField(“    ”);
    	//          (    )
    		Field field=c.getDeclaredField("    “);
    		//  java      
    		field.setAccessible(true);
    //       
    field.set(obj,   )//         
    
    

    5.反射によるメンバーの取得方法
    //         
    Class c=Class.forName(person   )
    Constructor con =c.getConstructor();
    Object obj=con.newInstance();
    
    //        
    	//           
    	Method[] methods=c.getMethods();
    	//         (    )
    	Method[] methods=c.getDeclaredMethods();
    //        
    	//           (       )
    	Method method=c.getMethod(“    ”);
    	//          (    )
    		Method method=c.getDeclaredMethod("    “,   class  );//         ,   class   :String.class
    		//  java      
    		method.setAccessible(true);
    //      
    method.invoke(obj,  )//         
    

    三、動的代理
    1.意味:
  • 実行中にオブジェクトが生成され、実行時にクラスを変更する方法に切り込むことができ、事前に定義する必要はありません.
  • javaの動的エージェントメカニズムには、Proxy(Class)、InvocationHandler(Interface)の2つの重要なクラスとインタフェースがあります(JDKが提供するエージェントはインタフェースのみをエージェントとし、クラスをエージェントとしてcglibを使用することができます).
  • 各動的エージェントクラスは、InvocationHandlerというインタフェースを実装する必要があり、各エージェントクラスのインスタンスはhandlerに関連付けられており、エージェントオブジェクトを介してメソッドを呼び出すと、このメソッドの呼び出しはInvocationHandlerというインタフェースのinvokeメソッドに転送されます.

  • 2.作成手順
  • エージェントが必要なインタフェース
    public interface StudentDao {
    	abstract void  identify(int s);
    	abstract void  dream();
    }
    
  • を作成する
  • エージェントインタフェース
    package proxy;
    public class StudentImpl implements StudentDao{
    	@Override
    	public void identify(int s) {
    		System.out.println("  "+s+"   "+"  ");
    	}
    	@Override
    	public void dream() {
    		System.out.println("   ");
    	}
    }
    
  • を実装する.
  • インプリメンテーションInvocationHandlerインタフェース:
    public class InvocationHandlerImpl implements InvocationHandler{
    	public Object target;
    	InvocationHandlerImpl(Object target){
    		this.target=target;
    	}
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		//System.out.println(proxy);
    		System.out.println("        ");
    		Object result=method.invoke(target, args);
    		return result;
    	}
    }
    
  • インタフェースエージェントを生成し、
    public class TestProxy {
    	public static void main(String[] args) {
    		StudentDao sd=new StudentImpl();
    		System.out.println("   :"+"
    "+"------------------------------------"); sd.dream(); sd.identify(5); System.out.println("------------------------------------"); // InvocationHandlerImpl h=new InvocationHandlerImpl(sd); StudentDao sdProxy=(StudentDao)Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), h); System.out.println(" :"+"
    "+"------------------------------------"); sdProxy.dream(); sdProxy.identify(5); System.out.println("------------------------------------"); } }
  • をテストする.
    テスト結果:
       :
    ------------------------------------
       
      5     
    ------------------------------------
       :
    ------------------------------------
            
       
            
      5     
    ------------------------------------
    
    

    四、設計モード
    1.設計思想:
    1.1単一職責思想設計原則:
  • クラスごとに1つの機能が実装され、変更の原因も1つしかありません.

  • 1.2開閉原則
  • クラスの変更は、修正コードではなく追加コードによって行われる(修正コードではなく、クラスの変更は追加コードによって行われる).抽象的および多様性を利用することが多い.
  • 1.3リッツ置換の原則
  • 親が現れる場所は、その子で置き換えることができるはずです.(同じ継承システムに共通の特徴がある)
  • 1.4依存注入の原則
  • 抽象クラスに依存し、特定の実装クラス
  • に依存しないでください.
    1.5インタフェース分離の原則
  • インタフェースは、クラスの削除変更を4つのインタフェースに分離する、各インタフェースが1つの機能を実現するなどの機能を提供する
  • .
    1.6ディミットの原則
  • クラスは、他のクラス(各クラス間の結合を低減する)
  • をできるだけ少なく理解しなければならない.
    2.設計モード
    2.1設計モードのいくつかの要素:
  • 名前は単純で意味のある名前でなければなりません
  • 問題は、モード
  • がいつ使用されるかを記述する.
  • ソリューションは、設計の構成要素と、問題をどのように解決するかを記述する
  • 効果記述モードの効果および長所と短所
  • 2.2設計パターンの分類
  • 作成型モードオブジェクトの作成
  • 単純ファクトリモード例:
    //  :Animal (eat  )
    //  :Cat  Dog   (   eat  )
        :
    Cat cat =new Cat();
    cat.eat();
    Dog dog=new Dog();
    dog.eat();
    //      :        (class   : AnimalFactory)
    public static  Animal createAnimal  (String type){
    	if("dog".equals(type)){
    		return new Dog();
    	}else if("cat".equals(type)){
    		return new Cat();
    	}else{
    		return null;
    	}
    }
    //      :
    Animal a=AnimalFactory.createAnimal("dog");//                ,      。
    a.eat();
    
  • 工場方法モデル例:
    //           ,                       。
    //  :Animal (eat  )
    //  :Cat  Dog   (   eat  )
    //   :Factory  (abstract  createAnimal());
    //   :DogFactory,CatFactory(  Factory  ,  createAnimal()  )
    //  :
    Factory f=new DagFactory();
    Animal a=f.createAnimal();
    a.eat();
    
    
  • 抽象工場モード
  • ビルダーモード
  • プロトタイプモード
  • 単一モード.

  • 構造型モードオブジェクトの構成(構造)
  • 外観モード
  • アダプタモード
  • プロキシモード
  • デコレーションモード
  • ブリッジモード
  • コンビネーションモード
  • 享元モード
  • 動作型モードオブジェクトの動作
  • テンプレート方法モード
  • オブザーバモード
  • 状態モード
  • 職責チェーンパターン
  • コマンドモード
  • ビジターモード
  • ポリシーモード
  • メモモード
  • 反復モード
  • インタプリタモード