Java学習ノート(七)反射および内部クラス

5764 ワード

反射:
反射:実行時に動的に解析するか、クラスを使用して作業します.
JAva.lang.Classクラス:クラス情報を記述するクラス.
≪クラス・オブジェクト|Class Objects|emdw≫:クラス情報を記述するオブジェクト.仮想マシンがクラスをロードすると、クラスのクラス・オブジェクトが作成され、そのオブジェクトがロードされます.Classはクラス・オブジェクトのタイプです.
クラスオブジェクトの取得方法:
このクラスのクラスオブジェクトをクラス名.classで取得します.
object.getClass()など、クラスのオブジェクトでgetClass()を呼び出して、このオブジェクトのタイプのクラスオブジェクトを取得します.
Class.forName(クラス名)を使用したり、このクラスのクラスオブジェクトを取得したりすることができます(注意、ここに書かれているクラス名は全限定定名(フルネーム)、パッケージ名にクラス名、XXXX.XX.XXXX)でなければなりません.
基本タイプにはクラスオブジェクトもあり、「パッケージクラス.TYPE」で対応する基本タイプのクラスオブジェクトを得ることができます.
JAva.lang.reflectパッケージの3つの重要なクラス:
Field属性クラス:属性を記述するための情報.
Methodメソッドクラス:メソッドの情報の説明.
Constructor構築メソッドクラス:構築メソッドを記述するための情報.
Classクラスでよく使用される方法:
newInstance() 
このClassオブジェクトが表すクラスの新しいインスタンスを作成します(非パラメトリック構造で作成されたオブジェクトを呼び出します).
getDeclaredMethods()
取得されたのはMethodメソッドクラスオブジェクトの配列であり、このクラス(親を含まない)が宣言したprivateを含むすべてのメソッドオブジェクトを取得します.
getMethods()    //推奨
取得したのはMethodメソッドクラスオブジェクトの配列であり、publiceのメソッドオブジェクトをすべて(親も含む)取得します.
getDeclaredConstructors()
取得したのはConstructor構築メソッドクラスオブジェクトの配列であり,このクラスが宣言したすべての構築メソッドオブジェクトを取得する.
getConstructors()    //推奨
得られたのはConstructor構築メソッドクラスオブジェクトの配列であり,すべてのpubliceの構築メソッドオブジェクトを得る.
getDeclaredFields()    //推奨
取得したのはField属性クラスオブジェクトの配列で、このクラスが宣言したすべての属性の属性オブジェクトを取得します.
getFields()
取得したのはField属性クラスオブジェクトの配列で、すべてのpubliceの属性オブジェクトを取得します.
反射を使用してクラスのオブジェクトを作成するには:
a.クラスオブジェクトの取得
b.構築方法の対象を得る
c.オブジェクトを取得し、構築方法オブジェクトで構築方法を呼び出し、無パラメトリック構築方法を使用する場合、第2のステップをスキップして、直接「クラスオブジェクト.newInstance()」方法を使用してこのクラスのオブジェクトを得ることができる
d.取得方法オブジェクト
e.メソッドオブジェクトでメソッドを呼び出す(このクラスのオブジェクトを第1パラメータとする)
次の例を示します.
反射メカニズムの実装クラス:
				package day07.reflect;				
				import java.lang.reflect.Field;
				import java.lang.reflect.Method;
				import java.util.HashMap;
				import java.util.Map;
				import java.util.Set;			
				public class TestReflect {					
					public static Object get(String className , Map map) throws Exception{
						Class c = Class.forName(className);                  //     
						Object o = c.newInstance();                   //    
						Set set = map.keySet();
						for(String str : set){
							String s = "set" + str.substring(0,1).toUpperCase()+str.substring(1);
							Field f = c.getDeclaredField(str);
							Method m = c.getMethod(s, f.getType());        //      
							m.invoke(o, map.get(str));                       //         
						}
						return o;
					}
					
					public static void main(String[] args) throws Exception {	
						Map m = new HashMap();
						m.put("name", "zhang");
						m.put("age", 22);
						Object o = get("day07.reflect.Student",m);
						Student s = (Student) o;
						System.out.println(s.getName() + "   " + s.getAge());
						
						Map m1 = new HashMap();
						m1.put("name", "li");
						m1.put("gender", " ");
						Object o1 = get("day07.reflect.Teacher",m1);
						Teacher t = (Teacher) o1;
						System.out.println(t.getName() + "    " + t.getGender());
					}
				}

学生クラス:
				package day07.reflect;				
				public class Student {
					private String name;				
					private int age;				
					public int getAge() {
						return age;
					}				
					public void setAge(int age) {
						this.age = age;
					}				
					public String getName() {
						return name;
					}				
					public void setName(String name) {
						this.name = name;
					}
				}	

教師:
				package day07.reflect;				
				public class Teacher {
					private String name;				
					private String gender;				
					public String getGender() {
						return gender;
					}				
					public void setGender(String gender) {
						this.gender = gender;
					}						
					public String getName() {
						return name;
					}				
					public void setName(String name) {
						this.name = name;
					}				
				}

内部クラス:
定義:
別のクラスに定義されているクラスは、内部クラスです.
コンパイル後に生成される2つの独立したクラス:Outer.classとOuter$Inner.class.
内部クラスの分類:
静的内部クラス静的内部クラスクラスクラスクラスクラス静的内部クラス定義クラス内
静的内部クラスは、外部クラスの静的メンバーにのみアクセスできます.
外部クラスの外部で、静的な内部クラスオブジェクトを作成するには、外部クラスオブジェクトは必要ありません.
Outer.Inner in = new Outer.Inner();
このクラス内で内部クラスオブジェクトを生成する方法:
Inner in = new Inner();
≪メンバー内部クラス|Member Internal Class|ldap≫:外部クラスのメンバーとして存在し、外部クラスの属性、メソッドと並べて表示されます.
内部クラスでは、外部クラスのプライベート属性に直接アクセスできます.
内部クラスと外部クラスのインスタンス変数は、名前の競合を許可します.
内部クラスでのインスタンス変数へのアクセス:this.プロパティ
内部クラスで外部クラスにアクセスするインスタンス変数:外部クラス名.this.プロパティ
外部クラスの外部で、メンバー内部クラスオブジェクトを作成するには、まず外部クラスオブジェクトを作成し、次にメンバー内部クラスオブジェクトを作成します.
Outer out = new Outer();
Outer.Inner in = out.new Inner();
このクラス内で内部クラスオブジェクトを生成する方法:
静的方法:Inner in=new Outer().new Inner();
非静的方法:Inner in=this.new Inner()
メンバー内部クラスには静的メンバーは使用できません.これは、静的プロパティがクラスをロードするときに作成され、このとき内部クラスが作成されていないためです.
ローカル内部クラス:外部クラスのメソッドで定義された内部クラス
ローカル変数と同様に、ローカル内部クラスの前に修飾子publicとprivateを追加することはできません.その役割ドメインはコードブロックを定義します.
ローカル内部クラスは、外部クラスのインスタンス変数だけでなく、外部クラスのローカル変数にもアクセスできますが、外部クラスのローカル変数はfinalである必要があります.
インタフェースと組み合わせて使用し、弱い結合を強制します.
外部クラスの外部ではローカル内部クラスオブジェクトは作成できません.ローカル内部クラスが存在するメソッドでのみ作成できます.
Inner in = new Inner();
匿名内部クラス匿名内部クラス:特殊なローカル内部クラス
名前もclass、extends、implementsキーワードもありません
1つのインタフェースを暗黙的に実装するか、クラスを継承し、インスタンスを1回しか作成できません.
実装方法:ある文でnew親/親インタフェース名(){クラス内実装方法}
例:
TreesSet ts = new TreeSet(new Comparator(){
						public int compare(Object o1, Object o2){
							return 0;
						}
					});

匿名の内部クラスがローカル内部クラスに属する場合、ローカル内部クラスのすべての制限が有効になります.
匿名内部クラスは、コンストラクタの名前がクラス名と同じでなければならないため、匿名内部クラスにはクラス名がない唯一の構造方法のないクラスです.