• Java的反射机制


    Class反射对象描述类语义结构,可以从Class对象中获取构造函数、成员变量、方法类等类元素的反射对象,并以编程的方式通过反射对象对目标对象进行操作。反射对象类定义在java.lang.reflect包中,主要包括三个主要的反射类:Constructor、Method、Field。

    Constructor

    类构造函数反射类,通过Class.getDeclaredConstructors()方法可以获得类的所有构造函数的反射对象数组。此外,还可以通过Class. getDeclaredConstructor(Class... parameterTypes)方法获取具体的构造函数的反射对象。

    该类有一个主要的方法newInstance(Object [] initargs)通过该方法可以创建一个类对象的实例

    注意:

    Class类中有4个方法可获取构造函数反射对象,其中getConstructors用来获取所有的公开的构造方法列表,getConstructor则根据参数类型来获取公开的构造方法。另外两个对应方法getDeclaredConstructors和getDeclaredConstructor的作用类似,只不过他们获取类中真正声明的构造方法,而忽略从父类中继承下来的构造方法(包括重写的构造函数)

    Method

    类方法的反射类,通过Class. getDeclaredMethods()方法获得类的所有方法反射类对象数组Method[]。此外,还可以通过Class.getDeclaredMethod(String name, Class... parameterTypes)方法获取类的具体方法反射类对象。

    该类主要的方法invoke(Object obj,Object[]args)

    注意:

    Class类中也有4个方法可获取方法反射对象,其中getMethods用来获取所有的公开的方法列表,getMethod则根据参数类型来获取公开的方法。另外两个对应方法getDeclaredMethods和getDeclaredMethod的作用类似,只不过他们获取类中真正声明的构造方法,而忽略从父类中继承下来的构造方法(包括重写的方法)

    Field

    类成员变量反射类,通过Class. getDeclaredFields()方法可以获得类的成员变量反射对象数组,通过Class. getDeclaredField(String name)方法可以获取类的具体的成员变量。

    该类主要方法set(Object obj,Object value) obj表示目标对象

    /**
     * 抽象类--基类
     * */
    public abstract class Person {
        
        public abstract String getSex();
        
        public void introduce() {
            System.out.println("I am a person.....");
        }
    }
    /*******************华丽的分割线***********************/
    /**
     * 子类(继承Person类)
     * */
    public class Man extends Person {
    
        private String name = "";
        
        private int age = 0;
        
        @Override
        public String getSex() {
            // TODO Auto-generated method stub
            return "man";
        }
    
        @Override
        public void introduce() {
            System.out.println("I am a man.....");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
        
        /**设置为私有*/
        @SuppressWarnings("unused")
        private String say() {
            return "My Name Is " + name + " And I am " + age;
        }
        
        @SuppressWarnings("unused")
        private void setNameAndAge(String name, Integer age) {
            setName(name);
            setAge(age);
        }
    }
    /*******************华丽的分割线*********************/
    /**
     * Java反射操作步骤:
     * 1---获取Class对象
     * 2---获取Class对象的方法反射对象、变量反射对象
     * */
    public class ReflectTest {
        
        public static void outputMethod(Class<?> clazz) {
            /**获取Class中的所有的方法(包括继承在父类中继承的方法)*/
            Method [] methods = clazz.getMethods();
            for(Method method : methods ) {
                System.out.println("ALL METHOD : " + method.getName());
            }
            /**获取Class中声明的方法(包括重实现父类的方法)*/
            methods = clazz.getDeclaredMethods();
            for(Method method : methods ) {
                System.out.println("DECLARED METHOD : " + method.getName());
            }
        }
        
        public static Method outputMethod(Class<?> clazz,String name,Class<?> params[]) throws Exception {
            /**获取Class中的声明的具体方法(包括继承在父类中继承的方法)*/
            Method method = clazz.getDeclaredMethod(name, params);
            System.out.println("SPECIFIC DECLARED METHOD : " + method.getName());
            return method;
        }
        
        
        public static void main(String []args) throws Exception {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            /**获取Class对象*/
            Class<?> clazz = loader.loadClass("com.qunar.reflect.Man");
            
            /**构造Person对象*/
            Man man = (Man) clazz.newInstance();
            
            /**获取Man的方法的反射对象*/
            ReflectTest.outputMethod(clazz);
            System.out.println("/*********************************/");
            Method method = ReflectTest.outputMethod(clazz, "setNameAndAge", new Class[]{String.class,Integer.class});
            /**允许调用私有方法*/
            method.setAccessible(true);
            method.invoke(man, new Object[]{"张晓龙",28});
            
            method = ReflectTest.outputMethod(clazz, "say", new Class[]{});
            /**允许调用私有方法*/
            method.setAccessible(true);
            String res =  (String) method.invoke(man, new Object[] {});
            System.out.println("Reflect Invoke Result : " + res);
        }
        
    }
  • 相关阅读:
    编辑推荐
    mybatis
    学习网址记录
    关于详情页的具体制作(四)
    关于详情页的具体制作(三)
    关于详情页的具体制作(二)
    关于详情页的具体制作(一)
    关于事件循环的一些总结
    vue生命周期的一些总结
    对于home主页的切换处理
  • 原文地址:https://www.cnblogs.com/hanfight/p/4153685.html
Copyright © 2020-2023  润新知