java反射机制简介

      在程序的运行期间,利用java的反射机制可以取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现的interfaces,也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。

      Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。java可以加载一个运行时才知道的class,获得其完整结构。


java反射机制所提供的功能

    在运行时判断任意一个对象所属的类
    
    在运行时构造任意一个类的对象
    
    在运行时判段任意一个类所具有的成员变量和方法
    
    在运行时调用任一个对象的方法
    
    在运行时创建新类对象

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
在 project 中定义 Person类

package com.runningbang.domain; 

      

     public class Person { 

         private String name; 

         private int age; 

         private float weight; 

         public Person() { 

         } 

         public Person(String name, int age, float weight) { 

             this.name = name; 

             this.age = age; 

             this.weight = weight; 

         } 

         //...... 

     }


    
   获取类的Class对象
    JAVA中获取Class对象有3种方式:

1.Class.forName() 

     2.Object.getClass()


    3.类字面常量 xx.class
    
    获取 Person 类的 全类名:

Person p = new Person(); 

         //获取Person类的字节码文件 

         Class<?> c = p.getClass(); 

         String className = c.getName(); 

         System.out.println(className);


        输出结果为:
            com.runningbang.domain.Person
        
    获取 Person 类的成员方法:

//获取类的所有成员方法,包括父类中的方法 

         Method[] m = c.getMethods(); 

         for (Method method : m) { 

             System.out.println(method); 

         }


    获取 Person类的成员属性:
        根据名称获取单个属性: Field name = Person.class.getDeclaredField("name");
        获取成员属性数组:Field[] fields = Person.class.getDeclaredFields();
    
    不管是属性还是方法 直接输出获取的 Method对象和Field对象 都是以下形式
        方法:访问修饰符 返回参数 全类名.方法名(参数列表)
            如 public void com.runningbang.domain.Person.say()
        属性:访问修饰符 类型 全类名.属性名称
            如 private java.lang.String com.runningbang.domain.Person.name
        也可以通过 Method 或 Field 类中定义的方法获取 方法或属性的String类型表示的名称
            如 method.getName(); 将返回 方法的名称
        
    获取类的构造方法:

Person.class.getConstructor(null);//根据指定的参数获取相应参数列表的构造方法 

         Person.class.getConstructors();//获取类的所有构造方法


    通过Class创建对象实例

Class<?> c = Class.forName("com.runningbang.domain.Person"); 

         Object o = c.newInstance();


        直接打印的结果为:com.runningbang.domain.Person@659e0bfd 对象

通过反射操作java类的属性

Class<?> c = Class.forName("com.runningbang.domain.Person"); 

             Object o = (Person)c.newInstance(); 

             Field f = c.getDeclaredField("name");//获取Person对象的 name属性 

             f.setAccessible(true);//由于属性的权限为 private 设置该属性的权限为可见的 

             f.set(p, "zhangsan"); 

             System.out.println(p.getName());


            打印结果为  张三 zhangsan



使用反射调用Java类的方法

Method m = c.getMethod("say", null);//获取Person对象的 say() 方法 

             m.invoke(p, null);//调用类方法 p 为 对应的对象,null 指该方法没有参数列表