android中的反射应用场景分析(map转化为bean工具)

android中用到反射的地方:
场景一:
在android的sdk中,有一些用hide标记的方法,或者是private方法 属性,这些方法不能直接通过sdk的api调用,如果我们需要用到此功能,只能通过反射的机制来调用它。
场景二:
在开发一些工具类的时候,例如网络数据,数据库数据和类之间的相互转化。使用反射机制可以直接创建对象,方便代码管理。
下面我们研究下反射的使用:
题外篇:
我们知道java程序的运行都是先将.java文件编译成.class 文件进行加载的。运行时候,如果我们要实例化某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。
参考http://blog.csdn.net/xiaoxian8023/article/details/9154227
下面我们进入正题:
反射的作用:
允许在程序正在执行的时候获取已知名称的类的内部信息,就是api中的自检。我们常需要用的有Class 内部信息 :Constructor(构造方法),Field(属性),Method(方法),Modifiers(修饰语),type(类型),Parametres(参数)
等等。一般我们使用反射的时候主要是创建实例,然后调用方法(功能),改变其属性等等。
下面是一个简单的Animal类:
package com.iwit.test;

public class Animal {
private int kind;
private String name;
private int age;
public Animal(){

}
public Animal(int kind, String name, int age) {
    super();
    this.kind = kind;
    this.name = name;
    this.age = age;
}
public int getKind() {
    return kind;
}
public void setKind(int kind) {
    this.kind = kind;
}
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;
}

}

1、获取Class
//通过class路径获取

    Class<?> c = Class.forName("com.iwit.test.Animal");
    //直接获取  
    Class<?> c = Animal.class
    //通过实例获取
    Class<?> c =new Animal().getClass();

2.创建一个实例
如果有空的构造方法直接实例化一个实例

1).Animal animal = (Animal) c.newInstance();   
如果我们知道构造方法,也可以通过结构体来实例化一个实例
(2).Constructor constructor = c.getConstructor(new Class<?>[] {int.class,String.class,int.class});
Animal  animal = (Animal)constructor.newInstance(new Object[]{1,"老虎",2});
第一种一般用在做公用的方法或者工具的时候用到;
第二种一般是已经知道构造方法,创建实例的时候用到。

3.获取所有的Field(属性)

Field[] fields = c.getDeclaredFields();

4.获取所有的方法。

Method[] methods = c.getMethods();

5.调用method方法 例子中调用setAge(int age),将老虎设置为两岁;

Method method0 = c.getMethod("setAge", int.class);
method0.invoke(animal, new Object[]{2});

6.获取Method 的参数类型

Class<?>[] cls = method.getParameterTypes();

7.获取Field的类型

Class<?>[] type = field.getType()

8.根据上面的内容就可以做一个将map转化为bean的工具。

package com.iwit.test;

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

public class Test {

    @SuppressWarnings("rawtypes")
    public static void main(String[] args) {
        try {
            new Animal().getClass();
            Class<?> c = Class.forName("com.iwit.test.Animal");

            Constructor constructor = c.getConstructor(new Class<?>[] {
                    int.class, String.class, int.class });
            Animal animal = (Animal) constructor
                    .newInstance(new Object[] { 1, "老虎", 2 });

            if (animal != null) {
                System.out.println("name:" + animal.getName());
            }
            Method method0 = c.getMethod("setAge", int.class);
            method0.invoke(animal, new Object[] { 2 });
            System.out.println("age:" + animal.getAge());
            // 获取他的所有的方法
            Method[] methods = c.getMethods();
            // 找出带有参数的方法 并且将animal的年纪改为5岁
            for (Method method : methods) {
                Class<?>[] cls = method.getParameterTypes();
                if (cls == null || cls.length == 0) {
                    continue;
                }
                String name = method.getName();
                Object[] params = new Object[cls.length];
                for (int i = 0; i < cls.length; i++) {
                    Class<?> cl = cls[i];
                    if (name.contains("Age") && cl.equals(int.class)) {
                        params[i] = 5;
                    }
                }
                if (name.contains("Age")) {
                    method.invoke(animal, params);
                }
            }
            if (animal != null) {
                System.out.println("age:" + animal.getAge());
            }

            // 我们在做工具的时候 就需要将获取到的属性和我们的set方法相对应 那么只需要
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("name", "大象");
            map.put("age", 5);
            map.put("kind", 10);


            animal = fillBean(c, map);
            if(animal == null){
                return;
            }
            System.out.println("age:" + animal.getAge());
            System.out.println("name:" + animal.getName());
            System.out.println("kind:" + animal.getKind());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 要注意 bean 必须要有空的构造方法
     * @param c
     * @param map
     * @return
     */
    @SuppressWarnings("unchecked")
    private static <T> T fillBean(Class<?> c, Map<String, Object> map) {
        T bean = null;
        try {
            // 先实例化一个
            bean = (T) c.newInstance();
            Field[] fields = c.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (map.get(fieldName) == null)
                    continue;
                Class<?> typeC = field.getType();
                System.out.println("typeC:" + typeC);
                Method method = c.getMethod(getSetterMethod(fieldName),
                        field.getType());
                if (getSetterMethod(fieldName).equals(method.getName())) {
                    method.invoke(bean, map.get(fieldName));
                };
            }
        } catch (Exception e) {
            System.out.println("map 转化为bean的时候出现异常:"+e);
        }

        return bean;
    }

    public static String getSetterMethod(String fieldName) {
        String firstC = fieldName.substring(0, 1);
        return "set" + fieldName.replaceFirst(firstC, firstC.toUpperCase());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值