第一篇博客,之所以想用博客记录下来,一是感觉自己的书写能力实在太差,还是需要学着写一些东西锻炼一下自己的书面表达能力,同时也当作笔记吧。由于都是按照自己的理解写的,可能会有一些错误,欢迎指正。
最近工作发现好多地方都用到了反射,由于刚接触Java,就有很多困惑对这块,所以就抽空了解了一下。
所谓反射,我的理解就是在Java运行过程中动态的去生成一个对象,获取类的基本结构,动态的调用对象的方法,设置其属性值等。Java反射机制主要有这么几个功能:
1.在运行的时候构造一个类的对象
2.在运行的时候判断一个对象所属的类
3.在运行时调用一个对象的方法(这个功能我遇到的最多)
3.在运行时获取所有的方法和属性
还是先通过代码来看一下反射的使用方法吧!
首先有一个类
public class Person{
//
}
获取这个类有三种方式:一种是通过Class.forName("包名.类名"),比如我的包名的Reflect
就可以通过Class.forName("Reflect.Person")获得该类。
另外还有通过对象的getClass()方法,比如new Person().getClass()方法得到。
还有一种就是person.class直接得到类。
通过上述三种任一种方法得到类之后,就可以调用newInstance()方法去实例化一个对象。比如
Class<?> demo= null;
demo= Class.forName("Reflect.Person");
Object myReflect = demo.newInstance(); </span>
通过这种方式就可以得到该类的对象。
假如在person类中定义三个属性
<span style="font-size:18px;">public class Person {
private String name;
private int age;
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Person(){
}
public Person(String name){
this.name = name;
}
public Person(int age){
this.age = age;
}
public Person(String name,int age){
this.name = name;
this.age = 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;
}
@Override
public String toString(){
return "["+this.name+" "+this.age+" "+this.address+"]";
}
}
对于这样一个类,如何通过反射去得到我们想要的东西呢?
首先,我们得到其所有的属性名字,可以这样来实现:
Class person = Class.forName("Reflect.Person");
Field[] fields = person.getDeclaredFields();
for(Field field : fields){
//属性名字
System.out.println(field.getName());
//属性类型
System.out.println(field.getType().getSimpleName());
//属性修饰符
System.out.println(Modifier.toString(field.getModifiers()));
}
其中,field.getModifiers()获取修饰符编码,是个整数,对应诸如public、private等,再通过Modifer.toString方法可以解码回我们熟悉的public等。
下面还是通过一个例子来看一下吧,该例子来源与网上,个人感觉挺不错的,就拿来了。
public class CopyByReflect {
public static Object copy(Object obj) throws Exception{
Class<?> cls = obj.getClass();
Object newObj = cls.getConstructor(new Class[]{}).newInstance(new Object[]{});
Field[] fields = cls.getDeclaredFields();
for(Field field: fields){
String name = field.getName();
String firstLetter = name.substring(0, 1).toUpperCase();
String getMethodName = "get"+firstLetter+name.substring(1);
String setMethodName = "set"+firstLetter+name.substring(1);
Method getMethod = cls.getMethod(getMethodName, new Class[]{});
Method setMethod = cls.getMethod(setMethodName, new Class[]{field.getType()});
Object value = getMethod.invoke(obj, new Object[]{});
setMethod.invoke(newObj, new Object[]{value});
}
return newObj;
}
public static void main(String args[]){
Person person = new Person();
person.setAddress("北京");
person.setAge(12);
person.setName("lisi");
try {
Object obj = copy(person);
Person per = (Person)obj;
System.out.println(per.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这个例子综合运用了几个常用的反射api实现了对一个类的复制。