美文网首页
Java Reflection

Java Reflection

作者: ZozoSpider | 来源:发表于2018-10-09 22:36 被阅读0次

    类的实例对象

    如何创建类的实例对象?

      1. 直接new
      1. 通过class实例化(需要有无参数的构造方法)

    CLass类的实例对象

    类本身也是一个实例对象,任何类都是Class类的实例对象。
    如何创建Class类都实例对象?

      1. 任何一个类都有一个隐含的静态成员变量class
      1. 通过该类对象的getClass方法
      1. Class.forName
    public class ClassDemo1 {
    
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    
            // Foo类的实例对象 方式1
            // 直接new
            Foo foo1 = new Foo();
            foo1.func();
    
            // Foo类本身也是一个实例对象,是Class类的实例对象,任何类都是Class类的实例对象,这个实例对象有三种表示方式如下
    
            // CLass类的实例对象 方式1
            // 任何一个类都有一个隐含的静态成员变量class
            Class clazz1 = Foo.class;
    
            // CLass类的实例对象 方式2
            // 通过该类对象的getClass方法
            Class clazz2 = foo1.getClass();
    
            // CLass类的实例对象 方式3
            // Class.forName
            Class clazz3 = Class.forName("reflection.ClassDemo1");
    
            // 官网clazz1, clazz2, clazz3表示了Foo类的类类型(Class type),不管clazz1, clazz2, clazz3都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
            System.out.println(clazz1 == clazz2 && clazz1 == clazz3); // True
    
            // Foo类的实例对象 方式2
            // 通过class实例化(需要有无参数的构造方法)
            Foo foo2 = (Foo) clazz1.newInstance();
            foo2.func();
        }
    
    }
    
    class Foo {
        void func() {
    
        }
    }
    

    静态加载与动态加载

    • 通过new,静态加载类,编译时加载所有可能用到的类
    • 通过Class.forName,动态加载类,运行时加载用到的类
    public interface Office {
    
        void start();
    
    }
    
    public class Word implements Office {
    
        public void start() {
            System.out.println("Word start");
        }
    
    }
    
    public class Excel implements Office {
    
        public void start() {
            System.out.println("Excel start");
        }
    
    }
    
    public class OfficeUser1 {
    
        public static void main(String[] args) {
    
            // 通过new,静态加载类,编译时需要加载所有可能用到的类
            if ("Word".equals(args[0])) {
                Word word = new Word();
                word.start();
            }
            if ("Excel".equals(args[0])) {
                Excel excel = new Excel();
                excel.start();
            }
    
        }
    
    }
    
    public class OfficeUser2 {
    
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    
            // 运行时动态加载类
            Class<?> clazz = Class.forName(args[0]);
            // 通过类类型,创建该类对象
            Office office = (Office) clazz.newInstance();
            office.start();
    
        }
    
    }
    

    常见类类型 & 运行结果

    public class ClassDemo2 {
    
        public static void main(String[] args) {
    
            // 基本数据类型class type
            Class clazz1 = int.class;
            Class clazz2 = double.class;
    
            // void返回类型class type
            Class clazz3 = void.class;
    
            Class clazz4 = Double.class;
            Class clazz5 = String.class;
    
            System.out.println(clazz1.getName());
            System.out.println(clazz2.getName());
            System.out.println(clazz3.getName());
            System.out.println(clazz4.getName());
            System.out.println(clazz5.getName());
            System.out.println(clazz5.getSimpleName());
    
        }
    
    }
    
    int
    double
    void
    java.lang.Double
    java.lang.String
    String
    

    解析Class的所有字段,方法,构造方法 & 运行结果

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class ClassUtil {
    
        /**
         * 解析Class的字段信息
         * @param obj
         */
        public static void printClassFields(Object obj) {
    
            // 传递的是哪个子类的对象,就是该子类的类型
            Class<?> clazz = obj.getClass();
            System.out.println("printClassField---------类名称:" + clazz.getName());
    
            // 获取所有public字段,包括父类
            Field[] fields = clazz.getFields();
    
            // 获取所有自己声明的字段,包括所有权限的
            Field[] declaredFields = clazz.getDeclaredFields();
    
            // 遍历所有字段
            for (Field field : fields) {
    
                // 成员变量类型的class type
                Class<?> type = field.getType();
                // 成员变量类型的名称
                String typeName = type.getName();
                System.out.print(typeName + " ");
    
                // 成员的名称
                String fieldName = field.getName();
                System.out.println(fieldName);
    
            }
    
        }
    
        /**
         * 解析Class的方法信息
         * @param obj
         */
        public static void printClassMethods(Object obj) {
    
            // 传递的是哪个子类的对象,就是该子类的类型
            Class<?> clazz = obj.getClass();
            System.out.println("printClassMethod---------类名称:" + clazz.getName());
    
            // 获取所有public方法,包括父类
            Method[] methods = clazz.getMethods();
    
            // 获取所有自己声明的方法,包括所有权限的
            Method[] declaredMethods = clazz.getDeclaredMethods();
    
            // 遍历所有方法
            for (Method method : methods) {
    
                // 方法的返回值的class type
                Class<?> returnType = method.getReturnType();
                // 方法的返回值的名称
                String returnTypeName = returnType.getName();
                System.out.print(returnTypeName + " ");
    
                // 方法的名称
                String methodName = method.getName();
                System.out.print(methodName + "(");
    
                // 所有方法参数的class type
                Class<?>[] parameterTypes = method.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    // 方法参数的名称
                    String parameterTypeName = parameterType.getName();
                    System.out.print(parameterTypeName + ", ");
                }
                System.out.println(")");
            }
    
        }
    
        /**
         * 解析Class的构造方法信息
         * @param obj
         */
        public static void printClassConstructors(Object obj) {
    
            // 传递的是哪个子类的对象,就是该子类的类型
            Class<?> clazz = obj.getClass();
            System.out.println("printClassConstructors---------类名称:" + clazz.getName());
    
            // 获取所有public构造方法,包括父类
            Constructor<?>[] constructors = clazz.getConstructors();
    
            // 获取所有自己声明的构造方法,包括所有权限的
            Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
    
            // 遍历所有构造方法
            for (Constructor<?> constructor : constructors) {
    
                // 构造方法的名称
                String constructorName = constructor.getName();
                System.out.println(constructorName + "(");
    
                // 所有方法参数的class type
                Class<?>[] parameterTypes = constructor.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    // 方法参数的名称
                    String parameterTypeName = parameterType.getName();
                    System.out.print(parameterTypeName + ", ");
                }
                System.out.println(")");
            }
    
        }
    
        public static void main(String[] args) {
            String s = "ss";
            ClassUtil.printClassFields(s);
            ClassUtil.printClassMethods(s);
            ClassUtil.printClassConstructors(s);
    
            System.out.println("------------------------------------------------");
    
            Integer i = 1;
            ClassUtil.printClassFields(i);
            ClassUtil.printClassMethods(i);
            ClassUtil.printClassConstructors(i);
        }
    
    }
    
    printClassField---------类名称:java.lang.String
    java.util.Comparator CASE_INSENSITIVE_ORDER
    printClassMethod---------类名称:java.lang.String
    boolean equals(java.lang.Object, )
    java.lang.String toString()
    int hashCode()
    void getChars(int, int, [C, int, )
    [B getBytes()
    java.util.stream.IntStream codePoints()
    ...
    printClassConstructors---------类名称:java.lang.String
    java.lang.String(
    [B, int, int, )
    java.lang.String(
    [B, java.nio.charset.Charset, )
    java.lang.String(
    [C, )
    ...
    ------------------------------------------------
    printClassField---------类名称:java.lang.Integer
    int MIN_VALUE
    int MAX_VALUE
    java.lang.Class TYPE
    int SIZE
    int BYTES
    printClassMethod---------类名称:java.lang.Integer
    int numberOfLeadingZeros(int, )
    boolean equals(java.lang.Object, )
    java.lang.String toString(int, int, )
    int min(int, int, )
    byte byteValue()
    short shortValue()
    java.lang.Integer getInteger(java.lang.String, java.lang.Integer, )
    int compareUnsigned(int, int, )
    void wait(long, int, )
    void wait()
    ...
    printClassConstructors---------类名称:java.lang.Integer
    java.lang.Integer(
    int, )
    java.lang.Integer(
    java.lang.String, )
    

    方法的反射 & 运行结果

    获取方法:方法的名称和方法的参数
    执行方法:method.invoke(对象, 参数列表);

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class MethodDemo1 {
    
        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
            // get class
            C c = new C();
            Class<? extends C> clazz = c.getClass();
    
            // get method
            Method method1b = clazz.getMethod("print", new Class[]{});
            Method method1a = clazz.getMethod("print");
    
            Method method2a = clazz.getMethod("print", new Class[]{String.class, String.class});
            Method method2b = clazz.getMethod("print", String.class, String.class);
    
            Method method3a = clazz.getMethod("print", new Class[]{int.class, int.class});
            Method method3b = clazz.getMethod("print", int.class, int.class);
    
            // invoke method
            c.print();
            Object return1a = method1a.invoke(c, new Object[]{});
            Object return1b = method1a.invoke(c);
            System.out.println("return1a: " + return1a);
            System.out.println("return1b: " + return1b);
    
            System.out.println("------------");
    
            c.print("hi", "world");
            Object return2a = method2a.invoke(c, new String[]{"hi", "world"});
            Object return2b = method2a.invoke(c, "hi", "world");
            System.out.println("return2a: " + return2a);
            System.out.println("return2b: " + return2b);
    
            System.out.println("------------");
    
            c.print(10, 20);
            Object return3a = method3a.invoke(c, new Object[]{10, 20});
            Object return3b = method3a.invoke(c, 10, 20);
            System.out.println("return3a: " + return3a);
            System.out.println("return3b: " + return3b);
        }
    }
    
    class C {
        // method1
        public void print() {
            System.out.println("hello, world!");
        }
    
        // method2
        public void print(String a, String b) {
            System.out.println(a + ", " + b);
        }
    
        // method3
        public int print(int a, int b) {
            System.out.println(a + ", " + b);
            return a + b;
        }
    }
    
    hello, world!
    hello, world!
    hello, world!
    return1a: null
    return1b: null
    ------------
    hi, world
    hi, world
    hi, world
    return2a: null
    return2b: null
    ------------
    10, 20
    10, 20
    10, 20
    return3a: 30
    return3b: 30
    

    相关文章

      网友评论

          本文标题:Java Reflection

          本文链接:https://www.haomeiwen.com/subject/zghuaftx.html