Java 反射原理

一、Java反射机制概述

        Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API
取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

正确方式: 引入需要的“包类”名称 --> 通过new实例化 --> 获取实例对象
反射方式: 实例化对象 --> getClass()方法 --> 得到完整“包类”名称

Java反射机制提供的功能:
  (1)在运行时判断任意一个对象所属的类
  (2)在运行时构造任意一个类的对象
  (3)在运行时判断任意一个类所具有的成员变量和方法
  (4)在运行时获取泛型信息
  (5)在运行时调用任意一个对象的成员变量和方法
  (6)在运行时处理注解
  (7)生成动态代理

反射相关的主要API:
  (1)java.lang.Class:                      代表一个类
  (2)java.lang.reflect.Method:        代表类的方法
  (3)java.lang.reflect.Field:            代表类的成员变量
  (4)java.lang.reflect.Constructor: 代表类的构造器
  (5)......

Person实体类:

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

    private Person() {

    }

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

    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;
    }

    public void show() {
        System.out.print("你好,我是一个程序员");
    }

    private String showNation(String name) {
        System.out.print("我的国际是:" + name);
        return name;
    }
}

MainApplication.java文件

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class MainApplication {
    /**
     * 主程序入口
     */
    public static void main(String[] args) {
        before();
        after();
    }

    /**
     * 反射之前:对Person的操作
     */
    public static void before() {
        //1.创建Person类的对象
        Person p1 = new Person("小米", 12);

        //2.通过对象,调用里面的属性、方法
        p1.age = 18;
        System.out.println(p1.toString());
        p1.show();

        //在Person类外部,不可通过Person类对象调用私有结构
        //比如:private showNation()
    }

    /**
     * 反射之后:对Person的操作
     */
    public static void after() {
        //Class反射源头
        Class clazz = Person.class;
        try {
            //1.通过反射创建Person类对象,得到指定构造器
            Constructor cons = clazz.getConstructor(String.class, int.class);
            Object obj = cons.newInstance("Tom", 24);
            Person p = (Person) obj;
            System.out.println(p.toString());
            //2.通过反射,调用对象指定的属性、方法
            //调用属性
            Field age = clazz.getDeclaredField("age");
            age.set(p, 10);
            System.out.println(p.toString());
            //调用方法
            Method method = clazz.getDeclaredMethod("show");
            method.invoke(p);
            //通过反射,可以调用Person类的私有结构。比如:私有构造器、属性、方法
            //调用私有的构造器
            Constructor dcons = clazz.getDeclaredConstructor(String.class);
            dcons.setAccessible(true);
            Person p1 = (Person) dcons.newInstance("leict");
            System.out.println(p1);
            //调用私有属性
            Field n1 = clazz.getDeclaredField("name");
            n1.setAccessible(true);
            n1.set(p1, "黄继光");
            System.out.println(p1.toString());
            //调用私有方法
            Method showNation = clazz.getDeclaredMethod("showNation", String.class);
            showNation.setAccessible(true);
            String nation = (String) showNation.invoke(p1, "中国");
            System.out.println("\n\r" + nation + "\n\r");

            System.out.println("getName---->>>>" + clazz.getName());
            System.out.println("getSimpleName---->>>>" + clazz.getSimpleName());
            System.out.println("getCanonicalName---->>>>" + clazz.getCanonicalName());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 效果如下:

posted @ 2020-04-17 13:12  逍遥散人95  阅读(161)  评论(0编辑  收藏  举报