Java中我们这样声明一个类,如人类
package cn.com.lcx.test;
public class Person {
public String sex = "男";
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
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;
}
public void say(){
System.out.println("姓名:"+name+",年龄:"+age+","+sex);
}
}
这是一个Person类型,java 类库中有 String类型,
不管是我们自定义的 类型还是 java类库中的类型 它们都有 构造函数、成员函数、成员属性,java中对象是对客观事物的抽象,类是对对象的抽象,所以java将所有的类型抽象成这样一个类型:Class类型。
我们用Person 类声明一个对象,Person p = new Person(); 这代表了一个具体的人类对象。
而我们的Class 类的对象就是具体的类如Person类,或者可以说是 Person类的那份二进制代码。我们可以通过以下3种方式声明Class 类的对象
Person person = new Person();
Class personClass1 = Person.class;//类名.class
Class personClass2 = person.getClass();//Person类对象的getClass方法
Class personClass3 = Class.forName("cn.com.lcx.test.Person");//类完整路径
这样我们就获取到了Person类的代码,Class 类 api中可以通过如下方法获取到 Class对象的构造函数、成员函数、成员属性等类元素的反射对象。
反射对象类,都在java.refect包总定义,主要有以下3个反射类:
Constructor.class:类中构造函数反射类
Method.class:类中方法反射类
Field.class:类的成员属性反射类
反射类和普通类一样都是对共有东西的抽象。
普通的方式访问成员函数或者成员属性是通过具体的对象去进行访问,
而反射是方法/属性对象针对某个具体对象进行调用或者访问的,这普通的方式好像是反着的,可能这就是反射的由来吧。
下面举个简单的例子进行抛砖引玉
package cn.com.lcx.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Refect {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) throws Exception {
//普通方式:实例化对象、调用方法、访问属性
Person person = new Person("普通人",0);//构造函数调用
person.sex = "男";//访问属性
person.say();//调用方法
Class personClass1 = Person.class;//类名.class
Class personClass2 = person.getClass();//Person类对象的getClass方法
Class personClass3 = Class.forName("cn.com.lcx.test.Person");//类完整路径
//Person类的构造函数反射类对象
Constructor personConstructor = personClass1.getConstructor(String.class,int.class);
System.out.println("通过反射实例化对象---------");
//通过构造函数反射类对象实例化Person类对象
Person person1 =(Person) personConstructor.newInstance("张一",1);
Person person2 = (Person) personConstructor.newInstance("张二",2);
Person person3 = (Person) personConstructor.newInstance("张三",3);
person1.say();
person2.say();
person3.say();
System.out.println("通过反射实现对对象成员方法调用---------");
//Person类的成员函数反射类对象
Method method = personClass2.getMethod("setName",String.class);
method.invoke(person1, "李一");
method.invoke(person2, "李二");
method.invoke(person3, "李三");
person1.say();
person2.say();
person3.say();
System.out.println("通过反射实现对成员属性的访问---------");
//Person类的成员属性反射类对象
Field field = personClass3.getField("sex");//获取公有属性
/**
* 获取私有属性或者私有方法用getDeclaredXXX方法,
* 如果想访问私有成员那么该属性对象或者方法对象要设置setAccessible(true)方法
*/
Field fieldPrivate = personClass3.getDeclaredField("name");
fieldPrivate.setAccessible(true);//设置可以访问私有属性
fieldPrivate.set(person, "反射人");
person.say();
field.set(person1, "男人");
field.set(person2, "女人");
field.set(person3, "人妖");
person1.say();
person2.say();
person3.say();
}
}