java反射的学习

 

1.类的 类类型(ClassType)

类的类类型可以用来做很多事,我们可以通过它获取到类的名称,类的路径,类的成员变量,类的方法等等,还可以通过它获得类的实例化对象。

我们可以通过 类名.class 来得到类的类类型,如下面的 c1

Class c1 = ReflectDemo.class;

 

我们可以通过类的实例对象得到类的类类型

ReflectDemo demo1 = new ReflectDemo();
Class c2 = demo1.getClass();

 

还可以通过类的包路径加类名获得类的类类型

Class c3 = Class.forName("reflectdemo.ReflectDemo");

值得注意的是,每个类只有一个类类型,也就是说上面的 c1, c2 , c3 指向的是同一个对象。

 

在开头也说了,类的类类型同样可以得到类的实例,所以两者可以相互得到。

类自身,类的类类型 和 类的实例对象 的关系如下图:

2.通过类的类类型获取类的成员变量以及方法

 自己写了一个方法,通过传入某个类的实例对象,就能得到该类的方法。

 其中 getMethod() 方法是获取类中所有public方法,包括父类的 public 方法;getDeclareMethod()方法可以获取本类中声明的所有方法,不论权限

    public static void getClassMethods(Object obj){
        Class c = obj.getClass();     //获取类类型
        Method []ms = c.getMethods();  //获取类中所有的public方法,包括父类中的方法
        Method []ms2 = c.getDeclaredMethods();  ////获取该类自己声明的所有方法,不论权限
        Field []fields = c.getFields();   //获取类中public级成员变量
        for(Field f:fields){
            String fieldType = f.getType().getSimpleName();   //获得成员变量类型
            String fieldName = f.getName();    //获得成员变量名
            System.out.println(fieldType+" "+fieldName);
        }
        
        for(Method m:ms){
            String type = m.getReturnType().getName();   //方法的返回值类型
            System.out.print(type+" ");
            String methodName=m.getName();        //方法名
            System.out.print(methodName+"(");
            Class []params = m.getParameterTypes();   //方法中 参数的类类型 元组
            
            for(Class param:params){
                String parName = param.getName();   //从参数类类型中得到参数名
                System.out.print(parName+" ");
            }
            System.out.println(");");
        }
        
    }

 

 3.通过反射来操作方法

除了上面通过getMethods()和getDeclaredMethods()获取方法数组之外,还可以通过getMethod()和getDeclaredMethod()来对单个方法进行查找。

这时就要注意,想要定位一个方法,必须要传入正确的方法名以及参数类类型才行。如下:

public class ReflectDemo2 {
    
    public void print(){
        System.out.println("a+b");
    }
    
    public String add(String a,String b){
        return a+b;
    }
    
    public int add(int a,int b){
        return a+b;
    }
}

 

我们想要获取对应的方法就要进行如下操作:

        ReflectDemo2 demo=new ReflectDemo2();
        Class c=ReflectDemo2.class;
        try {
            //通过传入的方法名称和参数类类型来获得某一确定方法的类类型
//            Method m1=c.getMethod("add", new Class[]{int.class,int.class});  //第一个参数为方法名,后面既可以传入一个类类型数组,也可以单独地传入类类型
            Method m1=c.getMethod("add",int.class,int.class); 
            Object obj = m1.invoke(demo, 10,20);   //通过invoke()来执行方法,要传入类的实例对象以及对应参数的值 
            System.out.println(obj);
            
            Method m2=c.getMethod("print");   //如果没有参数要传入,直接输入方法名即可
            m2.invoke(demo);   //如果方法没有返回值,可以不用获取
            } catch (Exception e) {
                e.printStackTrace();
            }
        
    }

结果和平常使用类的实例对象调用方法的结果是一样的。

 

待编辑。。

posted @ 2017-09-08 12:06  微啊微末  阅读(236)  评论(0编辑  收藏  举报