反射中Class、Method、Field、 Constructor类的使用
程序员文章站
2024-01-25 19:57:52
...
一、Class类
要想使用反射,首先需要获得该类或者该对象所对应的Class对象。常用的三种方式:
- 使用Class的静态方法forName:
Class<?> classType = Class.forName("java.lang.String");
2)使用类的.class方法:
Class<?> classType = String.class;
3)使用对象的getClass方法:
String s = "hello"; Class<?> classType = s.getClass();
二、Constructor类
1、 如果想通过类的不带参数的构造方法来生成对象,有两种放式:
1)先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:
Class<?> classType = String.class;
Object obj = classType.newInstance();
2)先获得Clsss对象,然后通过该Class对象获得对应的Constructor对象,再通过Constructor对象的newInstance()方法生成:
Class<?> classType = String.class;
Constructor cons = classType.getConstructor(new Class[] {});
Object obj = cons.newInstance(new Object[]{});
2、如果想通过类的带参数的构造方法来生成对象,只能通过下面一种方式:
Class<?> classType = String.class;
Constructor cons = classType.getConstructor(new Class[] {String.class, int.class});
Object obj = cons.newInstance(new Object[]{"hello", 3});
三、Method类
1、获取某类下的公有或全部方法
//获得类的public类型的方法
Method[] methods = classType.getMethods();
//获得类的所有方法
Method[] methods2 = classType.getDeclaredMethods();
2、获取某类下的一个具体方法
//得到add方法对应的Method,第一个参数是方法的名字,第二个参数是该方法参数类型的一个数组
Method addMethod = classType.getMethod("add", new Class[] {int.class, int.class});
四、Field类
1、获取某类下的公有或全部成员变量
Class<?> classType = String.class;
//获得对象的所有public成员变量
Field[] fields2 = classType.getFields();
//获得对象的所有成员变量
Field[] fields = classType.getDeclaredFields();
2、获取某类下一个具体的成员变量
//获得该类下的名为name的成员变量
Field field = classType.getField("name");
- 一个使用Class、Method、Constructor、Filed类的Demo
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
*使用Class、Method、Constructor、Filed类的Demo
*/
public class ReflectTester
{
/*
* copy(Object object)方法,这个方法能够创建一个和参数object 同样类型的对象,
* 然后把object对象中的所有属性拷贝到新建的对象中,并将它返回
*/
public Object copy(Object object) throws Exception
{
//传入参数是一个对象,所以用getClass()得到对应的Class
Class<?> classType = object.getClass();
//新建一个与object同类的对象,通过无参数构造方法
Object objectCopy = classType.getConstructor(new Class[]{})
.newInstance(new Object[] {});
//获得对象的所有public成员变量
Field[] fields2 = classType.getFields();
//获得对象的所有成员变量
Field[] fields = classType.getDeclaredFields();
for(Field field : fields)
{
String name = field.getName();
//获得该成员变量的首字母,并将其转化为大写
String firstLetter = name.substring(0, 1).toUpperCase();
//得到该成员变量的get和set方法的名字
String getMethodName = "get" + firstLetter + name.substring(1);
String setMethodName = "set" + firstLetter + name.substring(1);
//得到该成员变量的get和set方法
Method getMethod = classType.getMethod(getMethodName, new Class[] {});
Method setMethod = classType.getMethod(setMethodName, new Class[] {field.getType()});
//得到传入对象object的该成员变量的值
Object value = getMethod.invoke(object, new Object[] {});
//将value拷贝给objectCopy
setMethod.invoke(objectCopy, new Object[] {value});
}
return objectCopy;
}
public static void main(String[] args) throws Exception
{
Customer customer = new Customer("Tom", 20);
//由于id为Long类型,所以在传入参数的时候应该在数字后面加L
customer.setId(1L);
ReflectTester tester = new ReflectTester();
//实现拷贝
Customer customerCopy = (Customer)tester.copy(customer);
System.out.println(customerCopy.getId() + "," + customer.getName() +
"," + customer.getAge());
}
}
五、注意点
1、Integer.TYPE返回的是int,Integer.class返回的是Integer对应的Class。
转载于:https://www.jianshu.com/p/71b0a7790a2c