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());
}
}