Java反射基础

 

一.Java中反射的概念

  在Java中的反射机制,被称为Reflection。它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的package、 type parameters、 superclass、implemented interfaces、Inner class、outer class、fields、construtors、methods、modifier等,并可以在执行的过程中,动态的生成instance、变更fields内容或调用methods。总之一句话,Java反射就是动态的使用类。

 

二.实例化Class类,有三种方法:

  1.如果直接有一个类的对象 比如:

    Person p = new Person();

    Class clazz = p.getClass();

  2.如果知道类名,比如

    Class clazz = Person.class;

  3.如果只带全类名的话,比如:

    String className = "com.java.Person";

    Class clazz = Class.forName(className);

    一般来说,这种方法用来求类名不确定的类的镜象

三.代码示例:

  要被反射的类的代码ModelClass.java

  

 1 package test.java.reflection;
 2 
 3 public class ModelClass {
 4     private int id;
 5     private String name;
 6     
 7     public  ModelClass(){
 8         
 9     }
10     
11     public ModelClass(int id,String name){
12         this.id = id;
13         this.name = name;
14         
15     }
16     
17     public ModelClass(int id){
18         this(id,"xiaohu");
19     }
20     
21     public ModelClass(String name){
22         this(18,name);
23     }
24 
25     public int getId() {
26         return id;
27     }
28 
29     public void setId(int id) {
30         this.id = id;
31     }
32 
33     public String getName() {
34         return name;
35     }
36 
37     public void setName(String name) {
38         this.name = name;
39     }
40     
41     
42     
43 }

 

  1.根据类名获取类中所有的构造方法,以及参数类型,并打印

    Class clazz = Class.forName(className);

    claszz.getConstrctors();//返回类型是Constructor数组,此方法不能获取私有的(private)类型的构造函数

    clazz.getDeclaredConstructors();//返回类型是Constructor数组,获取类中所有的构造函数,包括private类型的。

    clazz.getConstructor(Class... parameterTypes);//获取特定参数的构造函数,参数的类型是Class类型的。此方法不能获取私有的构造函数

    clazz.getDeclaredConstructor(Class... parameterTypes);//获取特定参数的构造函数,参数的类型是Class类型的。此方法能获取所有的构造函数,包括私有(private)的

    Constructor类有个方法 getModifiers()返回值是int型的,int值对应一个修饰符。用Modifier.toString(int ) 可以获取到那个int值所对应的修饰符的Sring类型。

    具体代码如下:

  

 1 public static void getReflectionConstructors(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
 2         System.out.println("获取 "+className+" 类中的所有构造方法");
 3         //获取类的class镜像
 4         Class clazz = Class.forName(className);
 5         //获取构造器类的额的数组
 6         Constructor[] constructors = clazz.getDeclaredConstructors();
 7         for(int i=0;i<constructors.length;i++){
 8             int modi = constructors[i].getModifiers();
 9             String modifier = Modifier.toString(modi);
10             System.out.print(modifier +" " +className+" (");
11             Class[] paramters = constructors[i].getParameterTypes();
12             for(int j=0;j<paramters.length;j++){
13                 if(j!=0) System.out.print(",");
14                 System.out.print(Modifier. toString(paramters[j].getModifiers())+" "+paramters[j].getName());
15             }
16             System.out.println(")");
17         }
18     }

 

      结果截图如下:

 

          

     2.获取类中的所有属性的数据类型和修饰符,并打印

   

1 public static void getReflectionFelds(String className) throws ClassNotFoundException{
2         System.out.println("获取 "+className+" 类中的所有属性");
3         //获取类的镜象
4         Class clazz = Class.forName(className);
5         Field[] fields = clazz.getDeclaredFields();
6         for(int i=0;i<fields.length;i++){
7             System.out.println(Modifier.toString(fields[i].getModifiers())+" "+fields[i].getName());
8         }
9     }

   结果如下截图:

  

   3.获取类中所有方法,并打印

  

 1 public static void getReflectionMethods(String className) throws ClassNotFoundException{
 2         System.out.println("获取 "+className+" 类中的所有普通方法");
 3         //获取类的镜像
 4         Class clazz = Class.forName(className);
 5         //获取所有方法对应的类的数组
 6         Method[] methods  =clazz.getDeclaredMethods();
 7         //遍历所有方法
 8         for(int i=0;i<methods.length;i++){
 9               //获取所有方法的修饰符 ,返回值类型,方法名
10             System.out.print(Modifier.toString(methods[i].getModifiers())+
11                                     " "+methods[i].getReturnType().getName()+
12                                     " "+methods[i].getName()+"(");
13             //获取所有参数的类型对应的镜像
14             Class[] parametersType = methods[i].getParameterTypes();
15             for(int j = 0;j<parametersType.length;j++){
16                 System.out.print(parametersType[j].getName());
17                 if(parametersType.length>j+1)
18                     System.out.print(",");
19             }
20             System.out.println(")");
21         }
22         
23     }

  结果如下截图:

     

    4.根据类名创建实例,并根据类属性的名称,选择要调用的方法获取属性值

    代码如下:

  

 1 public static void getReflectionInstatnce(String className) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
 2         System.out.println("根据类名 "+className+" 创建实例并根据类属性的名称选择要调用的方法获取属性值");
 3         Class<?> clazz = Class.forName(className);
 4         Constructor<?> constructor = clazz.getDeclaredConstructor(int.class,String.class);
 5         ModelClass model = (ModelClass) constructor.newInstance(18,"xiaohu");
 6         //System.out.println("id = "+model.getId()+" name = "+model.getName());
 7         Field[] fields = clazz.getDeclaredFields();
 8         for(int i=0;i<fields.length;i++){
 9             //获取属性名的第一个字母,并转换为大写
10             String leftFirst = fields[i].getName().substring(0, 1).toUpperCase();
11             //获取属性名第一个字母以后的其他字符
12             String right = fields[i].getName().substring(1);
13             //拼接出get方法的名字
14             String methodName = "get"+leftFirst+right;
15             Method method = clazz.getDeclaredMethod(methodName);
16             System.out.println(fields[i].getName()+" = "+method.invoke(model));
17             
18         }
19     }

 

   结果如下:

    据类名 test.java.reflection.ModelClass 创建实例并根据类属性的名称选择要调用的方法获取属性值
    id = 18
    name = xiaohu

posted @ 2017-03-20 19:20  追风小虎  阅读(145)  评论(0编辑  收藏  举报