反射一(方法)

1.Class是什么?

     Class是一个类,是对象照镜子后可以得到的信息:某个类的数据成员名、方法何构造器、某个类到底实现了那些接口,对于美每个类,JRE都为其保留了一个不变的Class类型的对象,Class对象由系统建立,一个类在JTVM中只会有一个Class实例。 

2.Class 获取方法

(1)通过类的class属性获取

Class clazz = String.class;  //字符串为类名

(2)通过对象的getClass()方法获取

Class clazz = obj.getClass(); //obj为某个类的实例

(3)通过Class对象的forName()静态方法获取

Class clazz = Class.forName("className");//className为类的全限定名

3.Class类的方法

(1)创建Class对象的方法

Object obj = clazz.newInstance(); //clazz为Class类

注:此方法类必须含有无参构造器

(2)类加载器:用来把类(class)装载到JVM中。

ClassLoader loader = clazz.getClassLoader(); //当前类的类加载器是系统类加载器,还有扩展类加载器和指示类加载器

    关于类加载器的一个方法,资源获取:

InputStream in = loader.getResourceAsStream("path");//类加载器直接加载的是当前类目录下边的所有的class文件,包括其他的配置文件,即src下边的所有的文件。

4.反射:是java被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API获取到任何类的内部信息,并直接操作对象的内部属性及方法。

(1)获取方法:

       //可以本身及其父类的public方法
        Method[] methods = clazz.getMethods();
        for (Method method :methods){
            System.out.println(method);
        }
        //仅能获得本身的所有方法,包括私有的
        Method[] methods1 = clazz.getDeclaredMethods();
        for (Method method :methods1){
            System.out.println(method);
        }
        //根据方法名以及参数获取一个方法
Method method = clazz.getMethod("obj",Class<?>); //第一个参数为对象,第二个参数为方法的参数
 

(2)获取当前类的父类

Class superClazz = clazz.getSuperclass();

 (3)执行方法

        Object obj = new Student();
        Class clazz = obj.getClass();
        //根据方法名以及参数获取一个方法
        Method method = clazz.getMethod("print",int.class);
        //执行方法
        Object bj = method.invoke(obj,1);
        System.out.println(bj);

(4)当执行当前类的私有方法时,需要设置方法可访问

        Object obj  = new Student();
        Class clazz = obj.getClass();
        Method method =clazz.getDeclaredMethod("print1",int.class);//print1为private方法
        method.setAccessible(true);//设置私有方法可以访问
        method.invoke(obj,1);

(5)父类的私方法的获取和执行:

 //获取当前类或者其父的方法,包括私有方法
    public Method getMethod(Class clazz,String methodName,Class ...parameTypes) {
        //若在当前类找不到方法,将在其父类中找方法
        for(;clazz!=Object.class; clazz= clazz.getSuperclass()){
            //此处的异常必须用try-catch处理,并且catch不做任何异常抛出
            try {
               Method method = clazz.getDeclaredMethod(methodName,parameTypes);
                return method;
            } catch (NoSuchMethodException e) {
                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了 
            }
        }
        return null;
    }

    @Test
    public void testinvoke() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
        Object obj = new Student();
        Class clazz = Class.forName("reflect.Student");
        //当前类的私有方法
        Method method1 = getMethod(clazz,"print1",int.class);
        System.out.println(method1);
        method1.setAccessible(true);
        method1.invoke(obj,1);
        //父类的私有方法
        Method method2 = getMethod(clazz,"setIdAndName",int.class,int.class);
        method2.setAccessible(true);
        System.out.println(method2);
        method2.invoke(obj,2,1);
    }

 

 

   

 

posted @ 2019-03-26 20:34  yxqing  阅读(304)  评论(1编辑  收藏  举报