在Java的知识体系中,反射是不可或缺的一部分,通过反射可以实现反编译,获取任何一个类的对应的Class
实例,通过实例可以获得类或对象的所有信息。
java 中通过对象获取类的具体有如下三种方法:
- 通过
Class.forName()
, 如:Class clazz = Class.forName("java.lang.String");
- 通过类的
class
属性, 如:Class clazz = String.class;
- 通过实例对象的
getClass
方法, 如:Class clazz = user.getClass();
关于反射的详细总结参见:架构师之路:Java反射总结
现在我们来看一个这样的面试题:
有如下代码:
class ReadOnlyClass{
private Integer age =20;
public Integer getAge(){return age;}
}
现给定一个ReadOnlyClass的对象roc,能否把这个对象的age值改为30?
这是一个成员变量为私有的类,如果从常规的角度出发分析会发现,这个类仅提供了获取age的public方法,
而没有提供提供给修改age的方法,因而要完成该需求就必须借用反射。
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用
它的任意一个方法和属性;这种动态获取对象的信息以及动态调用对象的方法称为Java的反射机制。Java
反射机制容许程序在运行时加载,探知,使用编译期间完全未知的class。实现的代码如下:
package com.yang.reflct;
import java.lang.reflect.Field;
class ReadOnlyClass{
private Integer age=20;
public Integer getAge(){
return age;
}
}
public class Test1 {
public static void main(String[] args)throws Exception{
ReadOnlyClass pt = new ReadOnlyClass();
Class<?> clazz = ReadOnlyClass.class;
Field field = clazz.getDeclaredField("age");
field.setAccessible(true);
field.set(pt,30);
System.out.println(pt.getAge());
}
}
程序的运行结果为:30