Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以得到任意一个对象所属的类的信息,可以调用任意一个类的成员变量和方法,可以获取任意一个对象属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。

优点:实现动态创建对象和编译(即动态编译)

实例化Class对象共有以下三种方式:
(1)根据类名获取:类名.class
(2)根据对象获取:对象.getClass()
(3)根据全限定类名获取:Class.forName("全限定类名")

java 反射无法获取set方法 java反射获取所有方法_实例化

反射的应用:

通过反射可以得到一个类的完整结构,包括类的构造方法、类的属性、类的方法

以如下A类为例

java 反射无法获取set方法 java反射获取所有方法_实例化_02

(1)Constructor:表示类中的构造方法。

常用方法

java 反射无法获取set方法 java反射获取所有方法_构造方法_03

 无参构造实例化对象

public static void main(String[] args) throws ClassNotFoundException {
        Class<?> c1 = Class.forName("A");
        A a = null;
        try {
            a = (A)c1.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        a.setAge(18);
        a.setName("jack");
        System.out.println(a);
    }

 A{name='jack', age=18}

 有参构造实例化对象

(1)通过Class类中的getConstructors()方法获取本类中的全部构造方法。
(2) 向构造方法中传递一个对象数组,对象数组里面包含构造方法中所需的各个参数。
(3)通过Constructor类实例化对象。

try {
            Class<?> c1 = Class.forName("A");
            Constructor<?> cons[] = c1.getConstructors();
            //数组下标表示调用第几个构造方法
            A a1 = (A)cons[0].newInstance();
            System.out.println(a1);
            A a2 = (A)cons[1].newInstance("jack",18);
            System.out.println(a2);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

 A{name='null', age=0}
A{name='jack', age=18}

(2)Field:表示类中的属性。

 通过下列一组方法访问成员变量时,将返回Field类型的对象或数组。


getFields() getFied(String name) getDeclaredFieds() getDeclaredFied(String name)


访问访问指定的成员变量,可以通过该成员变量的名称来访问。

常用方法

java 反射无法获取set方法 java反射获取所有方法_java 反射无法获取set方法_04

public static void main(String[] args) throws ClassNotFoundException{
        Class<?> c2 = new A().getClass();
        Field f[] = c2.getDeclaredFields();// 取得本类属性
        for (int i = 0; i < f.length; i++) {
            int mod = f[i].getModifiers();// 得到修饰符数字
            String modifier = Modifier.toString(mod);// 取得属性的修饰符
            Class<?> r = f[i].getType();// 取得属性的类型
            String typeName = r.getName();
            String fieldName = f[i].getName();// 取得属性名称
            System.out.println("本类属性:" + modifier + " " + typeName + " " +
                    fieldName + ";");
        }
    }

本类属性:private java.lang.String name;
本类属性:private int age;

(3)Method:表示类中的方法。

通过下列一组方法访问方法时,将返回Method类型或数组

getMethods()
getMethod(String name,Class<?>... parameterTypes)
getDeclaredMethods()
getDeclaredMethod(String name,Class<?>... parameterTypes)

java 反射无法获取set方法 java反射获取所有方法_构造方法_05

以下案例获取ArrayList类中方法

try {
            Class<?> c = Class.forName("java.util.ArrayList");
            Method[] methods = c.getMethods();
            for (int i = 0; i < methods.length; i++) {
                String methodName = methods[i].getName();
                int methodModifiers = methods[i].getModifiers();
                Class<?>[] parameterTypes = methods[i].getParameterTypes();
                Class<?>[] exceptionTypes = methods[i].getExceptionTypes();
                System.out.println(
                        "方法名:" + methodName +
                        ", 修饰符:" + methodModifiers +
                        ", 全部参数类型:" + parameterTypes +
                        ", 全部抛出异常:" + exceptionTypes);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

(4)获取实现的类与接口

要取得一个类所实现的全部接口,必须使用Class中的getInterfaces()方法。

要取得一个类所继承的父类,调用getSuperclass()方法。

public static void main(String[] args) {
        Class<?> c = ArrayList.class;
        Class<?>[] interfaces = c.getInterfaces();
        Class<?> Super = c.getSuperclass();
        for (int i = 0; i < interfaces.length; i++) {
            System.out.println(
                    "ArrayList类实现的接口名称:"+ interfaces[i]+ c.getName()
            );
            System.out.println("父类名称:"+Super.getName());
        }
}

java 反射无法获取set方法 java反射获取所有方法_实例化_06