Java反射机制是动态语言的关键,反射机制允许程序在执行期间借助于reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
通俗的解释:Java是面向对象的语言,平时我们做任何事情都是先创建对象实例,让对象去干活(调用属性和方法)。但是有时候程序运行过程中某些对象是不确定的,比如方法是吃一个馒头,可以是一只人来吃,也可以是一个猴子来吃。只有程序运行时才知道具体是哪一类对象。反射机制能够在只知道某一种对象所属的类的情况下,从类出发,借助其提供的reflection API完成各种各样的在确定了类之后具体的功能。比如吃香蕉过程中噎住了,人是喝一点水,猴子是死命捶胸口...
反射的功能:1、在运行时判断任意一个对象所属的类。
2、在运行时构造任意一个类的对象。
3、在运行时判断任意一个类所具有的的成员变量和方法。
4、在运行时调用任意一个对象的成员和方法。
5、生成动态代理。
代码中有做详细的解释:
用于测试的User类:
public class User
{
public int id;
private String name;
private String password;
public User(){
}
public User(int id){
this.id = id;
}
public User(int id,String name,String password){
this.id=id;
this.name=name;
this.password = password;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getPassword(){
return password;
}
public void setPassword(String password){
this.password = password;
}
//增加一个private方法用于测试
private void print() {
System.out.println("id"+this.id+","+"name:"+this.name);
}
}
public class MyReflect
{
User user = new User(1001);
@Test
public void getClazz() throws Exception{
//Class是“类”所属的类
//通过类名获取对象找到对应的类
Class clazz = User.class;
//通过对象获取其对应的类
System.out.println((user.getClass()));
System.out.println(clazz);
//使用Class的静态方法
System.out.println(Class.forName("com.bean.User"));
//通过类反射生成对象
User user1 = (User) clazz.newInstance();
System.out.println(user1);
//获取到所有的构造方法
Constructor[] cons = clazz.getConstructors();
User user2=null;
for(int i=0;i<cons.length;i++){
//获取到对应的构造函数中所有的参数类型
Class[] cs= cons[i].getParameterTypes();
if(cs.length==1){
user2 = (User) cons[i].newInstance(1001);
}
}
System.out.println(user2);
}
//测试调用对象的属性
@Test
public void getField() throws Exception{
Class clazz = user.getClass();
//获取所有的public属性
Field[] fiel = clazz.getFields();
for(Field f:fiel){
System.out.println(f);
}
//获取到所有的属性
Field[] fiel1 = clazz.getDeclaredFields();
Object obj = clazz.newInstance();
for(int i=0;i<fiel1.length;i++){
//获取权限,因为属性可能是非public的
fiel1[i].setAccessible(true);
System.out.println(Modifier.toString(fiel1[i].getModifiers()));
//获取到属性的名称
System.out.println(fiel1[i].getName());
//获取类型fiel1[i].getType()
//getSimpleName()获取到属性的类型的名称
//System.out.println(fiel1[i].getType().getSimpleName());
if(fiel1[i].getType().getSimpleName().equals("int")){
fiel1[i].set(obj, Integer.parseInt("1"));
}
if(fiel1[i].getType().getSimpleName().equals("String")){
fiel1[i].set(obj, String.valueOf("张三"));
}
System.out.println(((User)obj).getName());
}
Field fi = clazz.getDeclaredField("name");
System.out.println(fi.getName()+"属性的类型:"+fi.getType());
}
//测试调用对象的方法
@Test
public void showMethod() throws Exception{
Class clazz = user.getClass();
Object obj = clazz.newInstance();
//获取所有的方法
Method[] method = clazz.getDeclaredMethods();
for(int i=0;i<method.length;i++){
System.out.println("方法名称:"+method[i].getName()+",方法的权限:"+Modifier.toString((method[i].getModifiers())));
}
//通过指定名称找到对应的方法,并且是无参方法
Method method2 = clazz.getDeclaredMethod("getName");
System.out.println("getName方法的返回值类型为:"+method2.getReturnType());
//如果对应的方法有参数,那么参数必须为参数的类型的类
Method method3 = clazz.getDeclaredMethod("setName",java.lang.String.class);
System.out.println(method3.getName());
}
}