Java反射机制处于运行状态,对于任何类,都可以知道该类的所有属性和方法;对于任何对象,都可以调用它的任何方法和属性,本文是错新技术频道小编和大家分享的详解Java反射机制的实现方法。
与反射有关的类包.
java.lang.reflect.*;和java.lang.Class;
Java中所有类型(包括基本类型)都对应一个Class对象,这个Class就是java.lang.Class。即每一个类型,在Class中都有一个Class对象跟它对应.Class 没有公共构造方法。注意不是没有,是没有公共的.
如何获得Class对象
每种类型的Class对象只有一个,即他们的地址只有一个,但是不同类型是不同的.
所以下面的打印结果都为true.
反射获取类中的成员的相关方法
[获取构造<根据参数类型>](使用时一般用不带declared的)
[获取属性<根据属性名>](使用时一般用是带declared的,因为属性一般都是私有的)
[获取方法<方法名加上参数类型>](使用时一般用不带declared的)
注意:
new Instance()调用的是无参构造,如果该类没有无参构造方法,则newInstance()会产生异常.
有declared的方法是支持私有,但是不支持继承,无declared的方法支持继承,不支持私有,且只能取出public的东西.
因此取属性的时候一般来说是带declared的,因为属性一般都是私有的,取方法时一般是不带declared的,取构造时一般也是不带declared的.
实例模拟反射获取类中的相关属性和方法
利用反射对属性赋值
Field中的方法
Object get(Object obj)
返回指定对象上此 Field 表示的字段的值。
Field f = c.getXXField(属性名);
值 = f.get(对象);
void set(Object obj, Object value)
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
f.set(对象,值);
Class<?> getType()
返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
用于获取属性的类型(返回Class对象).
利用反射调用构造
对于构造真正调用是在调用newInstance()方法时.
利用反射调用方法
对象.方法名(值1,2,3);
Method m = c.getMethoed(方法名,参数类型...);
m.invoke(对象,方法调用的参数 )如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。
反射应用实例
实体类
private String test;
public void execute(String name,int age){
System.out.println("name=" + name + ",age=" + age);
}
}
反射测试类
public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
Object obj = cls.newInstance(); //创建User的对象
Field f = cls.getDeclaredField("test"); //获取test属性
f.setAccessible(true); //打开私有属性test的访问权限
f.set(obj, "zhangsan"); //为test重新复制
System.out.println(f.get(obj)); //获取obj的test属性值
//根据方法名execute获取方法
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.invoke(obj, "dennisit",23); //调用execute方法
}
}
运行效果
编写一个反射动态实例化类的例子
public static Object getInstance(String className,Map<String,Object> map)throws Exception{
Class c = Class.forName(className);
Object obj = c.newInstance(); //对象对象
Set<String> keys = map.keySet(); //获取对应的所有属性
Field[] fAll = c.getDeclaredFields(); //获取类中所有属性
for(int i=0;i<fAll.length;i++){
for(String key:keys){ //循环匹配
if(fAll[i].getName().equals(key)){ //如果用户传入的属性跟获取到的类中的属性名匹配
Field f = c.getDeclaredField(key);//获取该属性
//构建setXxx()方法名
String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
Method method = c.getMethod(methodName, f.getType());//根据构建的用户名获取对应的方法
method.invoke(obj, map.get(key));//方法调用
}else{
continue;
}
}
}
return obj;
}
}
接下来我们测试我们编写的动态反射实例化例子
实体类
private String name;
private int age;
private String email;
public User() { //必须有无参构造
}
//getter() and setter()
}
主测试类
public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
String className = "org.dennisit.reflect.entity.User";
Map<String,Object> map = new HashMap<String, Object>();
map.put("name", "dennisit");
map.put("age", 22);
map.put("email", "dennisit@163.com");
User user = (User)DynamicReflect.getInstance(className, map);
System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
}
}
程序运行结果
以上就是关于详解Java反射机制的实现方法的内容,你学会了吗?如果你还想了解更多的技术知识,可以关注错新技术频道!
新闻热点
疑难解答
图片精选