Java Reflection

2018-10-09  本文已影响0人  ZozoSpider

类的实例对象

如何创建类的实例对象?

    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
上一篇下一篇

猜你喜欢

热点阅读