JAVA反射简介与使用示例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27607579/article/details/85282671

JAVA中的反射,所说的意思就是我们可以在程序运行期间内,动态获取某一个Class对象的所有信息,包括修饰符(modifiers),属性(fields),方法(methods)等。

举个例子就好比家里的防盗门,各种Class对象就是来敲门的各种人,当我们获取到一个未知其内容的Class对象的时候,就好比有一个没有预约的人来敲门,此时我们无法感知门外面的人是谁,他有可能是物业,有可能是外卖小哥,也有可能是查水表的。而反射就好比门眼,我们通过反射来观察未知其内容的Class对象,就好比通过门眼来观察门外的未知的人,这时,门外人的所有信息我们就可以通过门眼知晓了,他可能是穿着黄衣服的美团小哥,也可能是蓝衣服的饿了么小哥,而且高矮胖瘦,颜值如何,尽在我们的掌握。

但是反射也会消耗系统性能、增加程序复杂度,就好比你去把门眼的时候不得不放弃你正在进行的DOTA团战一样,所以,需要在合理的情形下使用才是最好的。


我们先创建需要用到的示例Class类:

ReflectTest:

package reflecttest;

public class ReflectTest {

    static{
        System.out.println("ReflectTest is init");
    }

    public String isPublicField = "defaultPublicField";

    protected String isProtectedField = "defaultprotectedField";

    String isDefaultField = "defaultDefaultField";

    private String isPrivateField = "defaultPrivateField";

    ReflectTest() {
        System.out.println("ReflectTest Constructor for no args");
    }

    public ReflectTest(String arg1) {
        System.out.println("ReflectTest Constructor for String arg1");
    }

    private ReflectTest(String arg1, String arg2) {
        System.out.println("ReflectTest Constructor for String arg1 and String arg2");
    }

    public void isReloadMethod(String arg1) {
        System.out.println("isReloadMethod for String arg1");
    }

    private void isReloadMethod(String arg1, String arg2) {
        System.out.println("isReloadMethod for String arg1 and String arg2");
    }

    public void isPublicMethod() {
        System.out.println("isPublicMethod");
    }

    protected void isProtectedMethod() {
        System.out.println("isProtectedMethod");
    }

    void isDefaultMethod() {
        System.out.println("isDefaultMethod");
    }

    private void isPrivateMethod() {
        System.out.println("isPrivateMethod");
    }

    public String getIsPublicField() {
        return isPublicField;
    }

    public void setIsPublicField(String isPublicField) {
        this.isPublicField = isPublicField;
    }

    public String getIsPrivateField() {
        return isPrivateField;
    }

    public void setIsPrivateField(String isPrivateField) {
        this.isPrivateField = isPrivateField;
    }

    public String getIsProtectedField() {
        return isProtectedField;
    }

    public void setIsProtectedField(String isProtectedField) {
        this.isProtectedField = isProtectedField;
    }

    public String getIsDefaultField() {
        return isDefaultField;
    }

    public void setIsDefaultField(String isDefaultField) {
        this.isDefaultField = isDefaultField;
    }
}

1. 进行反射,首先也是必要的,就是获取Class对象,一共有三种方法:

public static void main(String[] args) {
    /*
     注意:这种通过 类名.class 方式来获取class对象的方式并不会初始化ReflectTest类
      */
    Class c1 = ReflectTest.class;
    System.out.println("=====================");
    /*
     当我们获取到了一个Object对象,但是我们无法确定它属于哪个对象时
     我们可以通过 对象.getClass()的方式来获取这个对象的Class对象
      */
    Object reflectTest = new ReflectTest();
    Class c2 = reflectTest.getClass();
    System.out.println("=====================");
    try {
        /**
         * 当我们已知某个类的完整类路径名称的时候,可以通过Class.forName()方法来获取Class对象
         * 但是可能会抛出 ClassNotFoundException 异常
         */
        Class c3 = Class.forName("reflecttest.ReflectTest");
        /*
         * 每个类只会有一个class对象,因此通过以上三种方法得到的 c1、c2、c3 其实是同一个对象
         * 因此互相之间equals为true
         */
        System.out.println(c1.equals(c2));
        System.out.println(c1.equals(c3));
        System.out.println(c2.equals(c3));
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

控制台打印如下:

2. 获取到Class对象后,通过Class对象获取Class内容的常用方法如下:

getName():获取类的名称(包名 . 类名)

getFields():获取类的所有public修饰的属性

getField(String name):获取类的符合指定名称的public修饰的属性,无法获取default、protected、private修饰的属性

getDeclaredFields():获取类的所有属性,包含public、protected、default、private修饰的属性

getDeclaredField(String name):获取指定名称的field属性,包含public、protected、default、private修饰的属性

getMethods():获取所有的public修饰的方法

getMethod(String name, Class<T>... parameterTypes):获取符合指定方法名称与参数列表的public修饰的方法,第一个参数为方法名称,其余后面的参数都依次为参数列表的各个参数类型

getDeclaredMethods():获取类的所有方法,包含public、protected、default、private修饰的方法

getDeclaredMethod(String name, Class<T>... parameterTypes):获取符合指定名称与参数列表的方法,包含public、protected、default、private修饰的方法,第一个参数为方法名称,其余后面的参数都依次为参数列表的各个参数类型

getConstructors():获取类的所有的public修饰的构造函数

getConstructor(Class<T>... parameterTypes):获取类的符合指定参数列表的public修饰的构造方法

getDeclaredConstructors():获取类的所有的构造函数,包含public、protected、default、private修饰的构造函数

getDeclaredConstructor(Class<T>... parameterTypes):获取类的符合指定参数列表的构造方法,包含public、protected、default、private修饰的构造方法

newInstance():通过该类的无参构造函数进行对象实例化


代码示例:

getName():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getName() 方法获取类的完整类路径名称
        System.out.println(classObj.getName());
    }

执行结果:


getFields():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getFields() 方法获取所有的 public 修饰符修饰的field属性
        Field[] publicFields = classObj.getFields();
        Arrays.stream(publicFields).forEach(System.out::println);
    }

执行结果:


getField(String name):

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getField(String name) 方法获取指定名称的 public 修饰的field属性,无法获取非public修饰的field
        try {
            Field publicField = classObj.getField("isPublicField");
            System.out.println("publicField:"+ publicField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            Field protectedField = classObj.getField("isProtectedField");
            System.out.println("protectedField:"+ protectedField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            Field defaultField = classObj.getField("isDefaultField");
            System.out.println("defaultField:"+ defaultField);
        } catch (NoSuchFieldException e) {
        e.printStackTrace();
        }
        try {
            Field privateField = classObj.getField("isPrivateField");
            System.out.println("privateField:"+ privateField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

执行结果:


getDeclaredFields():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getFields() 方法获取所有的 public 修饰符修饰的field属性
        Field[] publicFields = classObj.getDeclaredFields();
        Arrays.stream(publicFields).forEach(System.out::println);
    }

执行结果:


getDeclaredFields():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getDeclaredField(String name) 方法获取指定名称的field属性,包含public、protected、default、private修饰的属性
        try {
            Field publicField = classObj.getDeclaredField("isPublicField");
            System.out.println("publicField:" + publicField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            Field protectedField = classObj.getDeclaredField("isProtectedField");
            System.out.println("protectedField:" + protectedField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            Field defaultField = classObj.getDeclaredField("isDefaultField");
            System.out.println("defaultField:" + defaultField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            Field privateField = classObj.getDeclaredField("isPrivateField");
            System.out.println("privateField:" + privateField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

执行结果:


getMethods():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getMethods()方法会获取所有的public修饰的方法
        Method[] methods = classObj.getMethods();
        Arrays.stream(methods).forEach(System.out::println);
    }

执行结果:


getMethod(String name, Class<T>... parameterTypes):

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        Method method;
        // getMethod(String name, Class<T>... parameterTypes)方法会获取符合指定名称与参数列表的public修饰的方法
        try {
            method = classObj.getMethod("isReloadMethod", String.class);
            System.out.println("String.class(public):" + method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            method = classObj.getMethod("isReloadMethod", String.class, String.class);
            System.out.println("String.class, String.class(private):" + method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            // 因为本身ReflectTest类就不具备参数列表为只接受一个Integer类型的isReloadMethod方法,所以会报出没有目标方法的异常
            method = classObj.getMethod("isReloadMethod", Integer.class);
            System.out.println("Integer.class(not exits):" + method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

执行结果:


getDeclaredMethods():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // getDeclaredMethods()方法会获取所有的方法
        Method[] methods = classObj.getDeclaredMethods();
        Arrays.stream(methods).forEach(System.out::println);
    }

执行结果:


getDeclaredMethod(String name, Class<T>... parameterTypes):

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        Method method;
        // getDeclaredMethod(String name, Class<T>... parameterTypes)方法会获取符合指定名称与参数列表的方法
        try {
            method = classObj.getDeclaredMethod("isReloadMethod", String.class);
            System.out.println("String.class(public):"+method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            method = classObj.getDeclaredMethod("isReloadMethod", String.class, String.class);
            System.out.println("String.class, String.class(private):"+method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            // 因为本身ReflectTest类就不具备参数列表为只接受一个Integer类型的isReloadMethod方法,所以会报出没有目标方法的异常
            method = classObj.getDeclaredMethod("isReloadMethod", Integer.class);
            System.out.println("Integer.class(not exits):"+method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

执行结果:


getConstructors():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        Constructor[] constructors = classObj.getConstructors();
        Arrays.stream(constructors).forEach(System.out::println);
    }

执行结果:


getConstructor(Class<T>... parameterTypes):

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        Constructor constructor;
        // getConstructor(Class<T>... parameterTypes)方法会获取符合指定参数列表的public修饰的构造方法
        try {
            constructor = classObj.getConstructor();
            System.out.println("no args(default):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            constructor = classObj.getConstructor(String.class);
            System.out.println("String.class(public):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            constructor = classObj.getConstructor(String.class, String.class);
            System.out.println("String.class, String.class(private):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            // 因为本身ReflectTest类就不具备参数列表为只接受一个Integer类型的构造函数,所以会报出没有目标方法的异常
            constructor = classObj.getConstructor(Integer.class);
            System.out.println("Integer.class(not exits):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

执行结果:


getDeclaredConstructors():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        Constructor[] constructors = classObj.getDeclaredConstructors();
        Arrays.stream(constructors).forEach(System.out::println);
    }

执行结果:


getDeclaredConstructor(Class<T>... parameterTypes):

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        Constructor constructor;
        // getDeclaredConstructor(Class<T>... parameterTypes)方法会获取符合指定参数列表的构造方法
        try {
            constructor = classObj.getDeclaredConstructor();
            System.out.println("no args(default):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            constructor = classObj.getDeclaredConstructor(String.class);
            System.out.println("String.class(public):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            constructor = classObj.getDeclaredConstructor(String.class, String.class);
            System.out.println("String.class, String.class(private):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            constructor = classObj.getDeclaredConstructor(Integer.class);
            System.out.println("Integer.class(not exits):" + constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

执行结果:


newInstance():

    public static void main(String[] args) {
        Class classObj = ReflectTest.class;
        // newInstance()方法会通过该类的无参构造函数进行对象实例化
        try {
            Object reflectTest = classObj.newInstance();
            System.out.println(reflectTest);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

执行结果:

猜你喜欢

转载自blog.csdn.net/qq_27607579/article/details/85282671