首页 > 代码库 > Java的反射机制

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);    }    }

 

Java的反射机制