利用類反射模擬內省功能

YX_blog發表於2015-09-03

當我們用一個物件的時候,不知道里面含有什麼,但是我們需要去封裝他,所以我們必須用到裡面的函式,方法等。

準備工作 需求:

定義一個Model類,裡面所有的屬性都是private的,然後為每個屬性提供getter和setter方法;再準備一個Map,map的key值都是類裡面的屬性欄位的字串表示,值任意。

設計一個方法Object getModel(Map map,Class cls),傳入一個包含所有值的Map,然後再傳入Model類的class,那麼返回Model類的例項,這個例項裡面已經包含好了所有相關的資料。也就是把Map中的資料通過反射,設定回到Model類例項中。 

提供的類為Person,僅僅就是為了一個用裡面的函式而已

package cn.hncu.reflect.neisheng.vo;

public class Person {
	String name;
	int age;
	public Person(String name, int age) {
		
		this.name = name;
		this.age = age;
	}
	public Person(){}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	
}

真的實現功能在這裡 將Map 和 CLass檔案利用起來

/**
 * 
 */
package cn.hncu.reflect.neisheng;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author xinxin
 *
 */
public class MapFactory {
	public static Object getModel(Map map,Class c) throws Exception{
		<span style="color:#ff0000;">Object obj1=c.newInstance();;//例項化,必須寫在前面,應為這裡的設定是針對同一個物件,所有必須在進行變數操作之前例項化</span>
		
		Field field[] =c.getDeclaredFields();//獲得所有的變數
		for(Field fld:field){
			Object obj =map.get(fld.getName());//通過變數名來使用
			if(obj==null){
				System.out.println(fld.getName()+"欄位為空");
			}else{
//				System.out.println("111111111");
				<span style="color:#ffcc33;">//變數名必須得到,根據自動生成的規則 setAge
</span>				Class cl[]=new Class[1];//引數型別,通過變數獲取
				cl[0]=fld.getType();//getType()返回一個 Class 物件,它標識了此 Field 物件所表示欄位的宣告型別。
				String methodname ="set"+fld.getName().substring(0, 1).toUpperCase()+fld.getName().substring(1);
				Method methods=c.getDeclaredMethod(methodname, cl);//呼叫根據條件獲得方法
//				
				Object[] ss=new Object[1];
				ss[0]=obj;//將map中的values放到不同的key
				methods.invoke(obj1, ss);//呼叫invoke
			}
		}
		return obj1;//返回傳進來的物件
	}
}
將其利用起來,使用一個類Client,就是一個通用的,只要裡面含有相應的key值,就能封裝進去

/**
 * 
 */
package cn.hncu.reflect.neisheng;

import java.util.HashMap;
import java.util.Map;

import cn.hncu.reflect.neisheng.vo.Person;
import cn.hncu.reflect.neisheng.vo.UserModel;

/**
 * @author xinxin
 *
 */
public class Client {

	
	public static void main(String[] args) {
		Map<String, Object> map =new HashMap<String, Object>();
		map.put("uuid", "100");
		map.put("name", "jack");
		map.put("pwd", "1");
		map.put("type", 2);
		try {
			UserModel user =(UserModel) MapFactory.getModel(map, UserModel.class);
			System.out.println(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("-------------------");
		
		
		Map<String, Object> map2=new HashMap<String, Object>();
		map2.put("name", "TOm");
		map2.put("age", 20);
		
		Person p=null;
		try {
			//p = (Person) MapFactory.getModel(map, Person.class);//要是這裡同樣使用之前的map,同樣會在函式裡面去匹配,但是要是key值沒有,也不能使用
			p = (Person) MapFactory.getModel(map2, Person.class);
			System.out.println(p);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(p);
		
	}

}

相關文章