认识JAVA反射

目录

一、Class类的使用与动态加载类

二、JAVA获取方法、成员变量、构造函数信息

三、方法反射的基本操作


一、Class类的使用与动态加载类

package com.study.reflect;

/**
 * 类功能描述:Class类的使用
 *
 * @author:***
 * @createTime:2018/11/12 16:33
 */
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //任何一个类都是Class的实例对象,这个实例对象有三种表达方式 c1==c2==c3
        //c1 c2 c3 是DemoA的类类型(class type)
        DemoA demoA = new DemoA();
        Class c1 = demoA.getClass();
        Class c2 = DemoA.class;
        //Class.forName动态加载类(运行时加载类) new是静态加载类(编译时加载类)
        Class c3 = Class.forName("com.study.reflect.DemoA");
        System.out.println(c1 == c2 && c2 == c3 && c3 == c1);  //输出true

        //通过类类型创建该类的对象实例 newInstance()
        ((DemoA) c1.newInstance()).print();   //输出print

    }

}

class DemoA {
    void print() {
        System.out.println("print");
    }
}


二、JAVA获取方法、成员变量、构造函数信息

class DemoA {
    public void print() {
        System.out.println("print");
    }

    public static void main(String[] args) throws NoSuchMethodException {
        DemoB.printMethodInfo("hello");
        DemoB.printMethodInfo(1);
    }
}

class DemoB {

    public static void printMethodInfo(Object obj) throws NoSuchMethodException {
        Class objClass = obj.getClass();
        //java.lang.String
        System.out.println("类名称为:" + objClass.getName());
        //String
        System.out.println(objClass.getSimpleName());
        //getMethod获取所有public的函数,包括父类继承而来的
        System.out.println(objClass.getMethod("toString").getName());
        //getDeclaredMethod获取的是所有该类自己声明的方法,无视访问权限
        System.out.println(objClass.getDeclaredMethod("toString").getName());

        //方法也是对象
        //遍历方法列表
        Method[] methods = objClass.getMethods();
        for (Method method : methods) {
            System.out.print(method.getName() + "(");
            //遍历参数名,并打印
            Class[] parameterTypes = method.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                System.out.print(parameterTypes[i].getSimpleName());
                if (i < parameterTypes.length - 1) {
                    System.out.print(",");
                }
            }
            System.out.println(")");
        }

        //成员变量也是对象
        //遍历成员变量列表
        Field[] fields = objClass.getFields();
        for (Field field : fields) {
            //遍历成员遍历并打印
            System.out.println(field.getType() + " " + field.getName());
        }

        //构造函数也是对象
        //构造函数列表
        Constructor[] constructors = objClass.getConstructors();
        for (Constructor constructor : constructors) {
            //构造函数方法名
            System.out.print(constructor.getName());
            //遍历构造函数参数列表
            Class[] typeParameters = constructor.getParameterTypes();
            System.out.print("(");
            for (int i = 0; i < typeParameters.length; i++) {
                //打印参数名
                System.out.print(typeParameters[i].getSimpleName());
                if (i < typeParameters.length - 1) {
                    System.out.print(",");
                }
            }
            System.out.println(")");
        }
    }

}

三、方法反射的基本操作

 
class DemoC {
    public void test(int a, int b) {
        System.out.println(a + b);
    }

}

class DemoA {
   /**
     * 反射就是将类别的各个组成部分进行剖析,可以得到每个组成部分,就可以对每一部分进行操作
     * 在比较复杂的程序或框架中来使用反射技术,可以简化代码提高程序的复用性。
     * 我对invoke理解:运用反射,可以避过编译时检查,
     * 像方法test可以通过入参的形式调用,如果没有test这个方法,使用传统的调用方式,编译都无法通过
     * 可以编写统一的反射方法,当增加或删除某个方法时,这个反射方法就不用做一些变动了,可以简化代码提高复用。
     * 类 方法 字段等都是在运行时才会执行,通过invoke方法,可以绕过编译。
     * 例如 ArrayList<String> arr = new ArrayList<>(); 可以通过反射绕过编译,从而添加进其他类型的值
     * Method method = arr.getClass().getMethod("add", Object.class);
     * method.invoke(arr, 20);
     * System.out.println(arr); 输出20,已经添加进去了
     */
    public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        DemoC democ = new DemoC();
        Method test = democ.getClass().getMethod("test", new Class[]{int.class, int.class});
        Object object = test.invoke(democ, new Object[]{10, 20});

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章