# Java高级之反射 **Repository Path**: fpfgitmy_admin/java-high-reflex ## Basic Information - **Project Name**: Java高级之反射 - **Description**: 反射简述 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-04-28 - **Last Updated**: 2021-04-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### Java反射机制概述 + Reflection(反射)是被视为**动态语言**的关键,反射机制允许程序在执行期借助于`Reflection API`获取任何类的内部信息,并且直接操作任意对象的内部属性及方法 + 加载完类之后,在堆内存的方法去中就产生了一个`Class`类型的对象(一个类只有一个`Class`·对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。**这个对象就像一面镜子,通过这个镜子可以看到类的结构,所以,我们形象的称之为:反射** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0428/113745_b1e2b90a_1942182.png "屏幕截图.png") #### 动态语言 + 是一类在运行时可以改变一结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是**在运行时代码可以根据某些条件改变自身的结构** + 主要动态语言:`Object-C、C#、JavaScript、PHP、Python、Erlang` #### 静态语言 + 与动态语言对应的,**运行时结构不可改变的语言就是静态语言**,如`Java、C、C++` + Java不是动态语言,但Java可以称之为**准动态语言**,即Java有一定的动态性,我们可以利用反射机制、字节码操作获得类似动态语言的特性 + Java的动态性让编程的时候更加灵活 #### Java反射机制提供的功能 + 在运行时判断任意一个对象所属的类 + 在运行时构造任意一个类的对象 + 在运行时判断任意一个类所具有的成员变量和方法 + 在运行时获取泛型信息 + 在运行时调用任意一个对象的成员变量和方法 + 在运行时处理注解 + 生成动态代理 #### 反射相关的API + `java.lang.Class`:代表一个类 + `java.lang.reflect.Method`:代表类的方法 + `java.lang.reflect.Field`:代表类的成员变量 + `java.lang.reflect.Constructor`:代表类的构造器 #### 通过反射调用构造器、属性、方法 1. 创建Person类 ``` package com.felixfei.study.model; /** * @describle */ 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 void show(){ System.out.println("你好"); } private String showNation(String nation){ System.out.println("国籍="+nation); return nation; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } 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; } } ``` 2. 进行调用 ``` package com.felixfei.study.test; import com.felixfei.study.model.Person; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @describle 反射的测试 */ public class TestReflection { public static void main(String[] args) throws Exception { // 一:1.通过反射创建Person类 Class personClass = Person.class; // 2.通过反射获取构造器 Constructor constructor = personClass.getConstructor(String.class, int.class); // 3.通过构造器实例化Person类为对象 Person person = constructor.newInstance("Tome", 12); System.out.println(person.toString()); // 二:通过反射调用对象指定的属性、方法 // 1. 通过创建的Person类获取 age 属性 Field age = personClass.getDeclaredField("age"); // 2. 进行age赋值 age.set(person,1); System.out.println(person.toString()); // 3.通过Person类获取方法 Method show = personClass.getDeclaredMethod("show"); // 4.进行方法的调用 show.invoke(person); } } ``` ##### 调用类的私有结构 ``` package com.felixfei.study.test; import com.felixfei.study.model.Person; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @describle 反射的测试 */ public class TestReflection { public static void main(String[] args) throws Exception { // 一:1.通过反射创建Person类 Class personClass = Person.class; // 获取构造器 Constructor personConstructor = personClass.getDeclaredConstructor(String.class); // personConstructor.setAccessible(true); // 调用私有构造器 Person person1 = personConstructor.newInstance("Jerry"); System.out.println(person1); // 调用私有属性 Field name = personClass.getDeclaredField("name"); name.setAccessible(true); name.set(person1, "HanMeimei"); // 调用私有方法 Method showNation = personClass.getDeclaredMethod("showNation", String.class); showNation.setAccessible(true); String showNation1 = (String) showNation.invoke(person1, "中国"); System.out.println("获取到的返回值=" + showNation1); } } ```