what
Java反射就是在运行状态中,
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
why
在运行时取得已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。还有动态代理的实现.
更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;
how
- 得到 Class 的三种方式
//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
// 类型的对象,而我不知道你具体是什么类,用这种方法
Person p1 = new Person();
Class c1 = p1.getClass();
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
// 这说明任何一个类都有一个隐含的静态成员变量 class
Class c2 = Person.class;
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
// 但可能抛出 ClassNotFoundException 异常
Class c3 = Class.forName("com.ys.reflex.Person");
- 通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
- 根据反射获取父类属性
public class Parent {
public String publicField = "parent_publicField";
protected String protectField = "parent_protectField";
String defaultField = "parent_defaultField";
private String privateField = "parent_privateField";
}
public class Son extends Parent {
}
public class ReflectionTest {
@Test
public void testGetParentField() throws Exception{
Class c1 = Class.forName("com.ys.model.Son");
//获取父类私有属性值
System.out.println(getFieldValue(c1.newInstance(),"privateField"));
}
public static Field getDeclaredField(Object obj,String fieldName) {
Field field = null;
Class c = obj.getClass();
for(; c != Object.class ; c = c.getSuperclass()){
try {
field = c.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}catch (Exception e){
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
//如果这里的异常打印或者往外抛,则就不会执行c = c.getSuperclass(),最后就不会进入到父类中了
}
}
return null;
}
public static Object getFieldValue(Object object,String fieldName) throws Exception{
Field field = getDeclaredField(object,fieldName);
return field.get(object);
}
}