U 需要知道的反射知识 – 大白话
1. 反射前言
.java
类文件会被编译为.class
二进制流文件,类加载器将其加载进入内存中,JVM
堆内存中会生成一个Class
对象,一个类对应于一个Class
对象,通过Class
对象可以获得其在方法区中存储的类完整结构信息,包括字段,方法等属性
2. 何为反射
- 反射 :程序在运行期间,可以通过
java
反射机制,动态获取某个类的结构信息(属性,方法等)- 动态 : 程序运行期间,无法修改源代码
- 静态 :通过
new
创建对象,然后调用某个类的字段或者方法,明确知道要使用的某个确定的类
- 总结 :通过反射机制,就能在程序运行期间,动态(用户自定义规则)去获取某个类的字段方法等属性
3.反射流程
以调用 Person
类中 public
get( )
为例
- 正常方式 :
import Person
类包名- 通过
new
关键字创建Person
对象p
- 对象调用方法
p.get( )
- 反射方式 :
- 通过
Person
全类名获取Class
类对象 - 通过
Class
对象 就可以得到访问当前Person
类的get( )
- 通过
4. 为什么要使用反射
-
反射基本是许多框架中使用到的技术,框架需要兼容每个使用者的要求,降低代码耦合度
-
反射提供动态处理,可以实现按需加载,有效减少不必要的类加载到内存
例如:
JDBC
获取数据库连接参数的方式 (见下 :实例讲解) -
后续示例中使用到的类
- 注解类
@Target({ ElementType.TYPE,ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value(); }
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Test { String value(); }
- Action 接口
interface Action{ void run(); public final String food = "肉"; //jdk11之后允许定义私有方法 private void privateEate(){ System.out.println("Action --> privateEate()");} private static void privateShow(){ System.out.println("Action --> privateShow()");} public static void publicShow(){ System.out.println("Action --> publicShow()");} }
- World 类
@Test(value = "world - Test") @MyAnnotation(value = "world - MyAnnotation") public class World { @MyAnnotation(value = "type") private String type; @MyAnnotation(value = "year") public int year; @Test(value = "origin") protected String origin; private String getType(){ return type;}; public int getYear(){ return year;} protected String getOrigin(){ return origin;} }
- Person 类
import java.util.ArrayList; @MyAnnotation(value = "person-MyAnnotation") @Test(value = "person Test") class Person extends World implements Action{ @MyAnnotation(value = "name") private String name; @Test(value = "sex") protected String sex; @MyAnnotation(value = "age") public int age = 20; private ArrayList<String> toys = new ArrayList<>(); public Person(String name, int age) { this.name = name;this.age = age;System.out.