2019独角兽企业重金招聘Python工程师标准>>>
假设我们有一个Master类,下面我开始对该类进行反射机制的研究:
class Master{
private String name;
private int 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;
}
public Master(String name,int age){
this.name=name;
this.age=age;
}
public Master(){
}
}
下面我来写一个ObjectUtil类,该类的私有变量和构造函数如下
private Map map=null;//用来存放待处理类中存在的属性以及属性类型
private static Object object;//我们要处理的类
public ObjectUtil(Object object){
this.object=object;
}
一. Field类
Field在jdk中的描述:提供有关类或接口的单个字段的信息,可以对它的动态访问权限。因此,我们可以根据field对象得到object中的属性名,属性类型和方法等信息。
/*
* 获取object的属性名
* */
public Map getNames(){
Field fields[]=object.getClass().getDeclaredFields();
map=new HashMap();
for (int i = 0; i < fields.length; i++) {
map.put(fields[i].getName(), fields[i].getType());
}
return map;
}
上面代码展示了如何通过Field获取对象中的属性名和该属性的类型,对应的方法分别是 field.getName()和field.getType()。
除了获取name和type,field类还有许多其他的方法,比如.getGenericType()返回的是getType()的string类型,
toGenericString()返回的是该字段笼统的概括 如:private java.lang.String com.text.Dog.name
getModifiers()返回的是该属性的范围的int值:public<==>1,private<==>2
set(object,objectVal)该方法的用途比较有限,要求属性是public类型的属性才能用,但大部分对象类是不会把属性设置成public的。它的第一个参数是类中的某个属性,第二个参数是该属性的值,相当于在类中中直接定义其他类的属性值:
Master master=new Master();
master.id=12;
二. Method类
下面我们通过class类获取对象属性的值,由于对象属性一般都是私有的,想获取属性的值必须执行get属性方法,所以我们需要通过构造get方法名来获得值
/*
* 根据object的属性名某对象该属性的属性值
* */
public Object getValue(String name){
if(map==null){
this.getNames();
}
String methodName="get"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
Method method;
Class class1=map.get(name);
Object valObject=null;
try {
method=object.getClass().getDeclaredMethod(methodName, new Class[]{});
valObject=method.invoke(object,new Object[]{});
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return valObject;
}
从上述代码中可以看出,
object.getClass().getMethod(methodName, new Class[]{});
可以构造出一个方法实例,方法名是methodName,方法中传入的参数类型是new Class[]{}
valObject=method.invoke(object,new Object[]{});
可以获取object对象在执行该方法的时候返回的对象,new object[]{}是对应参数,数量必须与上面的new class的数量相同不然报错,如果该方法是void方法,则返回null。
如果我们想让该方法返回string类型的值,只需把valObject强转为string即可,其它类型也相仿。
valObject=class1.newInstance();
该方法需要注意的是,假设我们要获取的属性真的是一个自定义的对象(比如在master中定义了一个dog类),这个对象的构造函数中不能有参数,这就是spring框架规定如果bean中非要写一个带参数的构造函数的话,必须重写一遍不带参数的构造函数 的原因。
get方法完成,我们来写最难的set方法:
/*
* set方法
* */
public ObjectUtil setValue(String name,Object valueObject){
String setMethod="set"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
if(map==null){
map=this.getNames();
}
Class class1=map.get(name);
Method method;
try {
method=object.getClass().getDeclaredMethod(setMethod, class1);
method.invoke(object, valueObject);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new ObjectUtil(object);
}
这里返回ObjectUtil的原因应该很容易理解了,这样就可以链式set值了,比如
ObjectUtil util=new ObjectUtil(new Master("xiaoli", 13));
util.setValue("age", 1).setValue("name", "xxx");
自此set、get方法完成,全部代码总结如下
package com.text;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.KeyStore.Entry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ObjectUtil {
private Map map=null;
private static Object object;
public ObjectUtil(Object object){
this.object=object;
}
public static void main(String[] args) {
ObjectUtil util=new ObjectUtil(new Master("xiaoli", 13));
util.setValue("age", 1).setValue("name", "xxx");
}
/*
* 获取object的属性名
* */
public Map getNames(){
Field fields[]=object.getClass().getDeclaredFields();
map=new HashMap();
for (int i = 0; i < fields.length; i++) {
map.put(fields[i].getName(), fields[i].getType());
}
return map;
}
/*
* 根据object的属性名某对象该属性的属性值
* */
public Object getValue(String name){
if(map==null){
this.getNames();
}
String methodName="get"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
Method method;
Class class1=map.get(name);
Object valObject=null;
try {
method=object.getClass().getDeclaredMethod(methodName, new Class[]{});
valObject=method.invoke(object,new Object[]{});
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return valObject;
}
/*
* set方法
* */
public ObjectUtil setValue(String name,Object valueObject){
String setMethod="set"+name.substring(0,1).toUpperCase()+name.substring(1,name.length());
if(map==null){
map=this.getNames();
}
Class class1=map.get(name);
Method method;
try {
method=object.getClass().getDeclaredMethod(setMethod, class1);
method.invoke(object, valueObject);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new ObjectUtil(object);
}
}
class Dog{
private String name;
private int id;
private Master master;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Dog(String name,int id,Master master){
this.name=name;
this.id=id;
this.master=master;
}
public Dog(){
System.out.println("被执行");
}
public Master getMaster() {
return master;
}
public void setMaster(Master master) {
this.master = master;
}
}
class Master{
private String name;
private int 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;
}
public Master(String name,int age){
this.name=name;
this.age=age;
}
public Master(){
}
}