JAva反射詳細実戦コード

12167 ワード

JAVA反射機構は運転状態において、いずれのクラスに対しても、このクラスのすべての属性と方法を知ることができる.任意のオブジェクトに対して、任意のメソッドと属性を呼び出すことができます.
Java反射メカニズムは主に以下の機能を提供している:実行時に任意のオブジェクトが属するクラスを判断する;実行時に任意のクラスのオブジェクトを構築します.実行時に任意のクラスが持つメンバー変数と方法を判断する.実行時に任意のオブジェクトを呼び出す方法.動的エージェントを生成します.
Class反射機構
  • とは、実行時にロード、コンパイル中に全く未知のクラスを探知、使用することができる.
  • プログラムは実行状態において、名前のみのクラスを動的にロードすることができ、ロードされたクラスのいずれかについて、このクラスのすべての属性と方法を知ることができる.任意のオブジェクトに対して、彼の任意のメソッドと属性を呼び出すことができます.
  • クラスのロードが完了すると、スタックメモリにClassタイプのオブジェクト(クラスに1つのClassオブジェクトしかない)が生成されます.このオブジェクトには完全なクラスの構造情報が含まれており、このClassオブジェクトは鏡のように、この鏡を通してクラスの構造が見えるので、反射と呼ばれます.
  • 各クラスがメモリにロードすると、システムはそのクラスに対応するjavaを生成する.lang.Classオブジェクトは、そのClassオブジェクトを介してJVMのこのクラスにアクセスすることができる.
  • Classオブジェクトの取得
  • オブジェクトのgetClass()メソッド;
  • 類class(最も安全/性能が最も良い)属性;
  • Classを運用する.forName(String className)はクラスを動的にロードします.classNameはクラスのフルネーム(最も一般的なもの)である必要があります.
  • コードで説明します.
    package com.lwl.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     *                
     * @create 2017-10-11   11:42:52
     * @version 1.0
     */
    public class ReflectAllDemo {
    
    	/**
    	 *                
    	 * @param args
    	 * @throws ClassNotFoundException 
    	 * @create 2017-10-11   9:07:46
    	 */
    	public static void main(String[] args) throws ClassNotFoundException {
    		
    		//                
    		//              ,          :ClassNotFoundException
    		Class> clazz = Class.forName("java.lang.String");
    		
    		//             
    		 Method[]	 methods = clazz.getDeclaredMethods();
    		 for (Method method : methods) {
    			System.out.println(method.toString());
    		}
    		 
    		System.out.println("------------------------------     :       --------------------------------"); 
    		//              
    		Field[] fields = clazz.getDeclaredFields();
    		for (Field field : fields) {
    			System.out.println(field.toString());
    		} 
    		
    		System.out.println("------------------------------     :       --------------------------------");
    		
    		//               
    		Constructor>[] constructor = clazz.getDeclaredConstructors();
    		for (Constructor> ctt : constructor) {
    			System.out.println(ctt.toString());
    		}
    		
    	}
    
    }
    
    オブジェクトの作成
    反射によってオブジェクトを生成する方法は2つあります.
  • ClassオブジェクトのnewInstance()メソッドを使用して、Classオブジェクトの対応クラスのインスタンスを作成する(この方法では、Classオブジェクトの対応クラスにデフォルトコンストラクタがあることが要求される).
  • Classオブジェクトを使用する指定したConstructorオブジェクトを取得してから、ConstructorオブジェクトのnewInstance()メソッドを呼び出して、そのClassオブジェクトに対応するクラスのインスタンスを作成する(このように指定したコンストラクタを選択してインスタンスを作成することができる).
  • 呼び出し方法
    クラスに対応するクラスオブジェクトを取得すると、そのクラスオブジェクトのgetMethodによってMethod配列またはMethodオブジェクトを取得することができる.
    各Methodオブジェクトは1つのメソッドに対応する、Methodオブジェクトを取得した後、invokeメソッドを呼び出すことによってそのMethodオブジェクトに対応するメソッドを呼び出すことができる.
    package com.lwl.reflect;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     *     ,          
     * @create 2017-10-11   11:45:57
     * @version 1.0
     */
    public class ReflectMethodDemo {
    
    	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
    		
    		
    		Class> clazz = Class.forName("com.lwl.reflect.Person");
    		//    
    		Object instance = clazz.newInstance();
    //		instance = clazz.getDeclaredConstructor(null).newInstance(null);
    		
    		//           ,          
    		Method method = clazz.getDeclaredMethod("setName", new Class[]{String.class});
    		//   
    		method.invoke(instance, new String[]{"jack"});
    
    		System.out.println(instance.toString());
    		
    		//   
    		Method getMethod = clazz.getDeclaredMethod("getName", new Class[]{});
    		Object getValue = getMethod.invoke(instance, new String[]{});
    		System.out.println(getValue);
    		
    		//             
    		Method staticMethod = clazz.getDeclaredMethod("printInfo", new Class[]{});
    		//       ,       instance     ,    null   
    		Object staticValue = staticMethod.invoke(instance, new String[]{});
    //		 staticValue = staticMethod.invoke(null, new String[]{});
    		System.out.println(staticValue);
    		
    	}
    
    }
    
    メンバー変数へのアクセス
    クラスに含まれるすべてのメンバー変数または指定されたメンバー変数Fieldは、ClassオブジェクトのgetField()メソッドによって取得できます.Filedは、次の2つのメソッドのセットを提供します.
    メンバー変数値の設定
    .
  • getXxx(Object obj):objオブジェクトのメンバー変数の値を取得します.ここでのXxxは8の基本タイプに対応し、メンバー変数のタイプが参照タイプであれば、getの後ろのXxxをキャンセルします.
  • setXxx(Object obj,Xxx val):objオブジェクトのメンバー変数値をval値に設定.ここでのXxxは8つの基本タイプに対応し、メンバータイプが参照タイプである場合、setの後ろのXxxをキャンセルします.
  • package com.lwl.reflect;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     *     ,          
     * @create 2017-10-11   11:45:20
     * @version 1.0
     */
    public class ReflectFieldDemo {
    
    	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
    		
    		//     
    		Class> clazz = Class.forName("com.lwl.reflect.Person");
    		//    
    		Object instance = clazz.newInstance();
    //		instance = clazz.getDeclaredConstructor(null).newInstance(null);
    		
    		//              
    		Field field = clazz.getDeclaredField("name");
    		//       
    		Class> type = field.getType();
    		System.out.println(type); //out print class java.lang.String
    		
    		//       
    		String name = field.getName();
    		System.out.println(name);  //out print name
    		
    		//  name   private,     setAccessible           
    		//setAccessible     ,            
    		field.setAccessible(true);
    		field.set(instance, "  ");
    		
    		System.out.println(instance.toString()); //out print Person [id=null, name=  , address=null]
    		
    	}
    
    }
    
    反射による値の割り当て
    package com.lwl.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     *     ,          
     * @create 2017-10-11   11:44:58
     * @version 1.0
     */
    public class ReflectSetValueDemo {
    
    	/**
    	 *               
    	 * @param args
    	 * @throws ClassNotFoundException 
    	 * @throws SecurityException 
    	 * @throws NoSuchFieldException 
    	 * @throws NoSuchMethodException 
    	 * @throws InvocationTargetException 
    	 * @throws IllegalArgumentException 
    	 * @throws IllegalAccessException 
    	 * @throws InstantiationException 
    	 * @create 2017-10-11   9:41:51
    	 */
    	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    
    		//    Class     
    		/*
    		 * 1. Class.forName(     :    )
    		 * 2.  .class   :Person.class
    		 * 3.   .getClass()  new Person().getClass();
    		 * */
    		Class> clazz = Class.forName("com.lwl.reflect.Person");
    //		clazz = new Person().getClass();
    //		clazz = Person.class;
    		
    		//      
    		Field field = clazz.getDeclaredField("address");
    		System.out.println(field.toString());
    		
    		System.out.println("--------------------------------------------     :          --------------------------------------------------------");
    		
    		//      
    		Method method = clazz.getDeclaredMethod("getName", new Class[]{});
    		
    		//   Class>                  ,           :java.lang.NoSuchMethodException
    		Method method1 = clazz.getDeclaredMethod("setName", String.class);
    		//       
    //		String name = method1.getName();
    		Method method2 = clazz.getDeclaredMethod("setInfo", String.class,Integer.class);
    		//method1   method2              
    		Method method3 = clazz.getDeclaredMethod("setName", new Class[]{String.class});
    		Method method4 = clazz.getDeclaredMethod("setInfo", new Class[]{String.class,Integer.class});
    		
    		System.out.println(method.toString());
    		System.out.println(method1.toString());
    		System.out.println(method2.toString());
    		System.out.println(method3.toString());
    		System.out.println(method4.toString());
    		
    		System.out.println("--------------------------------------------     :           --------------------------------------------------------");
    		//           ,      null    new Class[]{}
    		 Constructor> cs =  clazz.getDeclaredConstructor(new Class[]{});
    		 //       
    		 Constructor> cs2 =  clazz.getDeclaredConstructor(new Class[]{Integer.class,String.class,String.class});
    		 System.out.println(cs.toString());
    		 System.out.println(cs2.toString());
    		 
    		 
    		System.out.println("--------------------------------------------     :            --------------------------------------------------------");
    		//                 	 
    	    Object object =	cs.newInstance(new Object[]{});
    //	    object = cs.newInstance(null);
    	    //          ,       
    	    Object object2 =	cs2.newInstance(new Object[]{1,"  ","  "});
    //	    object2 = cs2.newInstance(null);
    		System.out.println("         :"+object); 
    		System.out.println("         :"+object2); 
    		
    		 
    		System.out.println("--------------------------------------------     :            :    --------------------------------------------------------");
    		
    		//        ,        
    		Method[] methods = clazz.getDeclaredMethods();
    		//        
    		Field[] fields = clazz.getDeclaredFields();
    		
    		for (Method m : methods) {
    			//       
    			String name = m.getName();
    			//      set   ,     
    			if(name.startsWith("set")){
    				//  set      ,      
    				String fieldName = name.substring(3);
    				//  set           ,                ,                  ,    UserName     username
    				fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
    				//             
    				//  Person       setInfo   , info      ,       
    				setFieldValue(fieldName, fields, m, object);
    			}
    		}
    		System.out.println("          :"+object); 
    		System.out.println("          :"+object2); 
    	    
    	}
    
    	/**
    	 *        
    	 * @param fieldName
    	 * @param fields
    	 * @param m
    	 * @param object
    	 * @throws IllegalAccessException
    	 * @throws IllegalArgumentException
    	 * @throws InvocationTargetException
    	 * @create 2017-10-11   10:41:53
    	 */
    	public static void setFieldValue(String fieldName, Field[] fields, Method m,  Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
    		
    		for (Field field : fields) {
    			if (field.getName().equals(fieldName)){
    				//       
    				Class> fieldClass = field.getType();
    				//   Integer       Person ID
    				if(fieldClass == Integer.class){
    					//       :     object  ,      m   ,    m        
    					m.invoke(object, new Integer[]{1});
    				}
    				//    String  2 set  ,                  
    				else if (fieldClass == String.class && "name".equals(fieldName)){
    					//       :     object  ,      m   ,    m        
    					m.invoke(object, new String[]{"jack"});
    				}
    				else if (fieldClass == String.class && "address".equals(fieldName)){
    					//       :     object  ,      m   ,    m        
    					m.invoke(object, new String[]{"  "});
    				}
    				//       
    				return;
    			}
    		}
    		
    	}
    	
    }
    
    使用する補助クラス:
    package com.lwl.reflect;
    
    public class Person {
    
    	
    	private Integer id;
    	
    	private String name;
    	
    	private String address;
    
    	public Person() {
    	}
    
    	public Person(Integer id, String name, String address) {
    		this.id = id;
    		this.name = name;
    		this.address = address;
    	}
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getAddress() {
    		return address;
    	}
    
    	public void setAddress(String address) {
    		this.address = address;
    	}
    	
    	public void setInfo(String name,Integer id){
    		this.id = id;
    		this.name = name;
    				
    	}
    
    	
    	public static void printInfo(){
    		System.out.println("      ,     ");
    	}
    	
    	@Override
    	public String toString() {
    		return "Person [id=" + id + ", name=" + name + ", address=" + address
    				+ "]";
    	}
    	
    	
    	
    	
    }