Loading

Java反射

反射概述

Java反射机制指的是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法。对于任意一个对象,都能够调用它的任意属性和方法,这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

反射常用类

  • ClassClass 类的实例表示正在运行的 Java 应用程序中的类和接口。
  • Constructor:关于类的单个构造方法的信息以及对它的权限访问。
  • Field:Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。
  • Method:Method 提供关于类或接口上单独某个方法的信息。

获取Class对象的方法

获取Class对象的的方法有以下几种:

  • 类名.class
Class<Person> clazz = Person.class;
  • 对象.getClass()
Person p1 = new Person();
Class clazz2 = p1.getClass();
  • Class.forName(全限定类名)
Class clazz3 = Class.forName("com.emhum.demo.Person");
  • 使用类的加载器,ClassLoader(这种方式了解即可)
ClassLoader classLoader = PersonTest.class.getClassLoader();
Class clazz4 = classLoader.loadClass("com.emhum.demo.Person");

反射示例

定义Person类:

public class Person {
    private String name;
    public int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void show() {
        System.out.println("你好啊!");
    }

    public String showAddress(String address) {
        System.out.println("我的地址是:" + address);
        return address;
    }
}

测试获取Person类的部分结构信息:

public class PersonTest {

    //使用反射,对Person进行操作
    @Test
    public static void test1() throws Exception {

        Class<Person> clazz = Person.class;
        //通过反射,创建Person类的对象
        Constructor<Person> cons = clazz.getConstructor(String.class, int.class);
        /**
         * newInstance():调用此方法,创建对应的运行时类的对象。
         *   1.运行时类必须提供空参的构造器
         *   2.空参的构造器的访问权限通常设置为public
         */
        Person p = cons.newInstance("tom", 12);
        System.out.println(p.toString());

        //通过反射,调用对象指定的属性和方法
        //调用属性
        Field age = clazz.getDeclaredField("age");
        age.set(p, 10);
        System.out.println(p.toString());

        //调用方法
        Method show = clazz.getDeclaredMethod("show");
        show.invoke(p);

        //通过反射,可以调用Person类的私有结构,比如:私有构造器,私有方法,私有属性。
        //调用私有构造器
        Constructor<Person> cons1 = clazz.getDeclaredConstructor(String.class);
        //保证此构造器是可访问的
        cons1.setAccessible(true);
        Person p1 = cons1.newInstance("jerry");
        System.out.println(p1);

        //调用私有的属性
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(p1, "tomas");
        System.out.println(p1);

        //调用私有的方法
        Method showAddress = clazz.getDeclaredMethod("showAddress", String.class);
        showAddress.setAccessible(true);
        showAddress.invoke(p1, "上海");
    }
}
posted @ 2021-12-03 09:35  charlatte  阅读(1211)  评论(0编辑  收藏  举报