package com.pinganfu.openapi.service;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class ReflectTest {

    static class Type {

        public int pubIntField;
        public String pubStringField;
        private int prvIntField;

        public Type() {
            Log("Default Constructor");
        }

        Type(int arg1, String arg2) {
            pubIntField = arg1;
            pubStringField = arg2;

            Log("Constructor with parameters");
        }

        public int getPrvIntField() {
            return prvIntField;
        }

        public void setPrvIntField(int prvIntField) {
            this.prvIntField = prvIntField;
        }

        private void Log(String msg) {
            System.out.println("Type:" + msg);
        }

    }

    static class ExtendType extends Type {

        public int pubIntExtendField;
        public String pubStringExtendField;
        private int prvIntExtendField;

        public ExtendType() {
            Log("Default Constructor");
        }

        ExtendType(int arg1, String arg2) {
            pubIntExtendField = arg1;
            pubStringExtendField = arg2;

            Log("Constructor with parameters");
        }

        public void setIntExtendField(int field7) {
            this.prvIntExtendField = field7;
        }

        public int getIntExtendField() {
            return prvIntExtendField;
        }

        private void Log(String msg) {
            System.out.println("ExtendType:" + msg);
        }

    }

    public static void testClassInstance() {

        Boolean foo = true;

        Class<?> obj1 = foo.getClass();
        Class<?> obj2 = Boolean.class;
        Class<?> obj3 = Boolean.TYPE;
        try {
            Class<?> obj4 = Class.forName("java.lang.Boolean");
            System.out.println(obj4);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(obj1);
        System.out.println(obj2);
        System.out.println(obj3);

    }

    public static void testGetFields() {

        /*
         * 可见getFields和getDeclaredFields区别: getFields返回的是申明为public的属性,包括父类中定义,
         * getDeclaredFields返回的是指定类定义的所有定义的属性,不包括父类的。
         */

        Class<?> classType = ReflectTest.ExtendType.class;
        System.out.println(classType);
        // 使用getFields获取属性

        Field[] fields = classType.getFields();
        for (Field f : fields) {
            System.out.println(f);
        }

        System.out.println("+++++");
        // 使用getDeclaredFields获取属性
        fields = classType.getDeclaredFields();

        for (Field f : fields) {
            System.out.println(f);
        }
    }

    public static void testGetMethods() {
        Class<?> classType = ExtendType.class;
        Method[] methods = classType.getMethods();
        for (Method m : methods) {
            System.out.println(m);
        }

        System.out.println("======");
        methods = classType.getDeclaredMethods();

        for (Method m : methods) {
            System.out.println(m);
        }
    }

    public static void testGetConstructos() {
        // 使用getConstructors获取构造器
        Class<?> classType = ExtendType.class;
        Constructor<?>[] constructors = classType.getConstructors();
        for (Constructor<?> m : constructors) {
            System.out.println(m);
        }

        System.out.println();

        // 使用getDeclaredConstructors获取构造器
        constructors = classType.getDeclaredConstructors();
        for (Constructor<?> m : constructors) {
            System.out.println(m);
        }
    }

    public static void testNewInstance() {
        Class<?> classType = ExtendType.class;
        Object inst1 = null;
        Object inst2 = null;
        Object inst3 = null;
        try {
            inst1 = classType.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Constructor<?> constructor1 = null;
        Constructor<?> constructor2 = null;
        try {
            constructor1 = classType.getConstructor();
            constructor2 = classType.getDeclaredConstructor(int.class, String.class);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            inst2 = constructor1.newInstance();
            inst3 = constructor2.newInstance(1, "123");
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(inst1);
        System.out.println(inst2);
        System.out.println(inst3);
    }

    public static void testInvokeMethods() {
        Class<?> classType = ExtendType.class;

        Object inst = null;
        try {
            inst = classType.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Method logMethod = null;
        try {
            logMethod = classType.getDeclaredMethod("Log", String.class);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            logMethod.setAccessible(true);// 不加这句,报private异常,
            logMethod.invoke(inst, "test");
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void testGetterAndSetter() {
        Class<?> classType = ExtendType.class;

        Object inst = null;
        try {
            inst = classType.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Field intField = null;
        try {
            intField = classType.getField("pubIntExtendField");
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            intField.setInt(inst, 100);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            int value = intField.getInt(inst);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        testSetter(classType, inst, "prvIntField", 10);
        System.out.println(testGetter(classType, inst, "prvIntField"));
    }

    public static Object testGetter(Class<?> classType, Object obj, String fieldName) {

        return testAccessField(classType, obj, fieldName, null, false);

    }

    public static void testSetter(Class<?> classType, Object obj, String fieldName, Object fieldVal) {

        testAccessField(classType, obj, fieldName, fieldVal, true);
    }

    private static Object testAccessField(Class<?> classType, Object obj, String fieldName, Object fieldVal, boolean flag) {
        Object fieldObj = null;

        Method[] methods = classType.getMethods();
        Method getMethod = null;
        Method setMethod = null;
        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i].getName());
            String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

            if (flag) {
                if (("set" + methodName).equals(methods[i].getName())) {
                    setMethod = methods[i];
                    break;
                }
            } else {
                if (("get" + methodName).equals(methods[i].getName())) {
                    getMethod = methods[i];
                    break;
                }
            }
        }

        try {
            if (flag) {
                if (setMethod != null) {
                    setMethod.setAccessible(true);
                    setMethod.invoke(obj, fieldVal);
                } else {
                    // field.set(obj, fieldVal);
                    System.err.println("error");
                }
            } else {
                if (getMethod != null) {
                    getMethod.setAccessible(true);
                    fieldObj = getMethod.invoke(obj);
                } else {
                    // fieldObj =field.get(obj);
                    System.err.println("error");
                }
            }

        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return fieldObj;
    }

    public static void testGetterAndSetter(Class<?> classType, Object obj, String fieldName, Object fieldVal) {

        Object fieldObj = null;
        /*
         * Field[] fields = classType.getFields();
         * 
         * Field field = null;
         * 
         * for (int i = 0; i < fields.length; i++) { if( fieldName ==
         * fields[i].getName()){ field = fields[i]; break; } }
         * 
         * if(field == null){ return ;}
         */

        Method[] methods = classType.getMethods();
        Method getMethod = null;
        Method setMethod = null;
        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i].getName());
            String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            if (("get" + methodName).equals(methods[i].getName())) {
                getMethod = methods[i];
                continue;
            }
            if (("set" + methodName).equals(methods[i].getName())) {
                setMethod = methods[i];
                continue;
            }
            if (getMethod != null && setMethod != null)
                break;
        }

        try {

            if (setMethod != null) {
                setMethod.setAccessible(true);
                setMethod.invoke(obj, fieldVal);
            } else {
                // field.set(obj, fieldVal);
                System.err.println("error");
            }

            if (getMethod != null) {
                setMethod.setAccessible(true);
                fieldObj = getMethod.invoke(obj);
            } else {
                // fieldObj =field.get(obj);
                System.err.println("error");
            }

        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println(fieldObj);

    }

    static interface Face {

        public void say();

        public int count();
    }

    static class RealTeller implements Face {

        @Override
        public void say() {
            System.out.println("hello");
        }

        @Override
        public int count() {
            // TODO Auto-generated method stub
            return 100;
        }

    }

    static class CommonHandler implements InvocationHandler {

        private Object target;

        public CommonHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // TODO Auto-generated method stub
            // System.out.println("proxy--"+proxy);
            // System.out.println("target--"+target);
            // System.out.println("Method:"+ method + ",Args:" + args);

            return method.invoke(target, args);
        }

    }

    public static Object testProxy(Object target) {

        // Face target = new RealTeller();
        Object proxy = (Face) Proxy.newProxyInstance(ReflectTest.class.getClassLoader(), target.getClass().getInterfaces(), new CommonHandler(target));
        return proxy;

    }

    public static void main(String[] args) {
        // testClassInstance();
        // testGetFields();
        // testGetMethods();
        // testGetConstructos();
        // testNewInstance();
        // testInvokeMethods();
        // testGetterAndSetter();
        Face face = (Face) testProxy(new RealTeller());
        System.out.println(face.getClass());

        face.say();

        System.out.println(face.count());
    }

}

本文转载:CSDN博客