Java 反射

看了很多关于反射的文章和例子,却从没有自己好好总结总结。Let’s do it。

反射相关的类和方法

java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;

获取Class的三种方式

    /**
     * 获取Class的三种方式
     */
    public static void testGetClass() {

        Class<?> c1 = null;
        Class<?> c2 = null;
        Class<?> c3 = null;

        try {
            // 第一种方式
            c1 = Class.forName("com.example.java.Employee");
        } catch (ClassNotFoundException e) {
            System.out.println("没有找到Employee类!");
            e.printStackTrace();
        }
        // 第二种方式
        c2 = Employee.class;

        // 第三种方式
        Employee employee = new Employee();
        c3 = employee.getClass();

        System.out.println("类名称, Name:" + c1.getName() + " , SimpleName:" + c1.getSimpleName());
        System.out.println("类名称, Name:" + c2.getName() + " , SimpleName:" + c2.getSimpleName());
        System.out.println("类名称, Name:" + c3.getName() + " , SimpleName:" + c3.getSimpleName());

}

运行结果:

类名称, Name:com.example.java.Employee , SimpleName:Employee
类名称, Name:com.example.java.Employee , SimpleName:Employee
类名称, Name:com.example.java.Employee , SimpleName:Employee

通过Class来创建对象

  public static void newInstanceFromClass() {

        Class<?> c = null;

        try {
            c = Class.forName("com.example.java.Employee");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        try {
            // Class.newInstance()方法会调用类的无参构造函数,所以类一定要有无参构造函数,要不然有出错。
            Employee employee = (Employee) c.newInstance();
            employee.setName("LiLei");
            employee.setAge(20);
            System.out.println(employee);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

【运行结果】

[ Name:LiLei, mAddress:null, mAge:20, mPhoneNumber:null ]

通过Class获取并使用类的构造函数

    /**
     * 通过Class获取类的构造函数,包含修饰符、名字、参数类型
     */
    public static void testGetConstructors() {
        Class<?> c = null;

        try {
            c = Class.forName("com.example.java.Employee");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Employee employee1 = null;
        Employee employee2 = null;

        // 获取所有的构造函数
        Constructor<?> constructors[] = c.getConstructors();
        StringBuilder sb = new StringBuilder();

        for (Constructor constructor : constructors) {
            //获得构造函数的修饰符,例如public,static等等
            sb.append(Modifier.toString(constructor.getModifiers()) + " ");
            // 获取构造函数的名字
            sb.append(constructor.getName());
            // 获取构造函数中的参数,如果没有参数,则返回length为0的数组。
            Class[] types = constructor.getParameterTypes();
            sb.append(" ( ");
            for (Class type : types){
                sb.append(type.getSimpleName()); // 获取参数的类型名字
                sb.append(" ");
            }
            sb.append(" ) ");
            sb.append("\r\n");
        }

        System.out.println(sb.toString());

        // 调用构造行数来初始化对象
        try {
            employee1 = (Employee) constructors[0].newInstance("Lucy", "USA", 29, "1892222222");
            employee2 = (Employee) constructors[1].newInstance();
            employee2.setName("Jack");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        System.out.println(employee1);
        System.out.println(employee2);
    }

通过Class获取类实现的接口


    /**
     * 通过Class获取类实现的接口
     */
    public static void testGetInterfaces() {
        Class<?> c = null;

        try {
            c = Class.forName("com.example.java.Employee");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // 获取实现的接口
        Class[] interfaces = c.getInterfaces();
        StringBuilder sb = new StringBuilder();
        sb.append("实现的接口有: ");
        for (Class i :interfaces) {
            sb.append(i.getName());
            sb.append(" ");
        }

        System.out.println(sb);
    }

通过Class获取类继承的父类

    /**
     * 通过Class获取类继承的父类
     */
    public static void testGetSuperclass() {
        Class<?> c = null;

        try {
            c = Class.forName("com.example.java.Engineer");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 获取父类
        Class<?> parent = c.getSuperclass();
        System.out.println("继承的父类:" + parent.getName());

    }

通过Class获取类的属性变量

   /**
     * 通过Class获取类的属性变量
     */
    public static void testGetFields() {
        Class<?> c = null;

        try {
            c = Class.forName("com.example.java.Engineer");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        StringBuilder sb = new StringBuilder();

        // getFields() 返回本类或者本接口中的属性字段,不包含父类或者接口中的。
        Field[] fields = c.getDeclaredFields();

        sb.append("本类或本接口的属性字段:\n");
        for (Field field : fields) {
            // 属性字段的修饰符
            sb.append(Modifier.toString(field.getModifiers()) + " ");
            // 属性字段的类型
            sb.append(field.getType().getSimpleName() + " ");
            // 属性字段的名字
            sb.append(field.getName());
            sb.append("\n");
        }

        // getFields() 返回可以访问的public的属性字段,包括本类和来自父类或者接口中的public的。
        fields = c.getFields();
        sb.append("public的属性字段:\n");
        for (Field field : fields) {
            sb.append(Modifier.toString(field.getModifiers()) + " ");
            sb.append(field.getType().getSimpleName() + " ");
            sb.append(field.getName());
            sb.append("\n");
        }

        try {
            Field field = c.getDeclaredField("isJunior");
            sb.append(field.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        System.out.println(sb);
    }

通过Class获取类的方法

  public static void testGetMethods() {

        Class<?> c = null;

        try {
            c = Class.forName("com.example.java.Engineer");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        StringBuilder sb = new StringBuilder();

        sb.append("本类或本接口的方法:\n");
        Method[] declaredMethods = c.getDeclaredMethods();
        for (Method method : declaredMethods) {
            // 方法修饰符
            sb.append(Modifier.toString(method.getModifiers()) + " ");
            // 方法返回类型
            sb.append(method.getReturnType().getName() + " ");
            // 方法名字
            sb.append(method.getName() + " ");
            sb.append("(");
            // 获取方法的所有参数
            for (Class type : method.getParameterTypes()) {
                sb.append(type.getName());
                sb.append(" ");
            }

            sb.append(") \n");
        }

        sb.append("所有public的方法:\n");
        // 返回可以访问的public的方法,包括本类和来自父类或者接口中的public的。
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            sb.append(Modifier.toString(method.getModifiers()) + " ");
            sb.append(method.getReturnType().getName() + " ");
            sb.append(method.getName() + " ");
            sb.append("(");

            for (Class type : method.getParameterTypes()) {
                sb.append(type.getName());
                sb.append(" ");
            }

            sb.append(")");

            // 获取方法会抛出的Exception的异常类型
            Class[] exceptionTypes = method.getExceptionTypes();

            if (exceptionTypes.length > 0) {
                sb.append(" throws ");
                for (Class type : exceptionTypes) {
                    sb.append(type.getName());
                    sb.append(" ");
                }
            }

            sb.append("\n");
        }

        System.out.println(sb);
    }

通过Class修改类的变量


    /**
     * 通过Class修改类的变量
     */
    public static void testModifyFiled() {

        Class<?> c = null;
        Object object = null;

        try {
            c = Class.forName("com.example.java.Engineer");
            object = c.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        try {
            Field field1 = c.getDeclaredField("isJunior");
            Field field2 = c.getField("mNickName");
            field1.setBoolean(object, true); // 修改属性变量
            field2.set(object, "NICE");      // 修改属性变量

            System.out.println(field1.getBoolean(object) + " " + field2.get(object));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        System.out.println(object.toString());
    }

通过Class来调用类的方法

   /**
     * 通过Class来调用类的方法
     */
   public static void testCallMethod() {

        Class<?> c = null;
        Object object = null;

        try {
            c = Class.forName("com.example.java.Engineer");
            object = c.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        try {
            Method method1 = c.getDeclaredMethod("setmLevel", int.class); // 获取本类中“setmLevel”的方法
            method1.invoke(object, 4); // 调用“setmLevel”方法

            Method method2 = c.getMethod("setName", String.class); // 获取父类中public的“setName”的方法
            method2.invoke(object, "Jonson");  // 调用“setName”方法

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        System.out.println(object.toString());
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值