运行状态下, 通过反射可以知道任意类的所有属性和方法,。对于任意一个实例对象, 都能调用其任意方法和属性。
1. 反射原理简单剖析:
1.1 A a = new A() -> 做了什么事情
- 类加载器加载A.class文件到内存中, 执行静态代码块和静态方法
- 执行new语句, 并在堆中申请一片内存空间.
- 调用构造函数, 实例化一个对象. 并逐级调用,初始化属性值。
疑问: 子类实例化对象, 会不会实例化父类对象??
首先答案肯定是: 子类实例化对象不会实例化对象, 举个简单的例子, 如果我的父类是一个抽象类, 子类继承抽象类。如果子类实例化对象同时也实例化父类对象, 那么就与抽象类不允许实例化有冲突了。只是会调用父类的构造函数对父类属性进行初始化。
1.2 Class文件 & Class类对象:
java文件在编译后会变成class文件, 并会在项目启动的时候由类加载器加载class文件到内存中, JVM根据其字节数创建Class对象. 
Class对象, 描述class文件, class文件中的构造器, 方法可以理解为组件, 对应Class对象的一个个字段。
字段、方法、构造器对象:
注解数据: 
泛型信息
例子:

一个Controller字节码文件, 在加载到内存的时候, 都会被解构保存到Class类中.
1.3 类加载过程 & 类加载器:
详见 https://www.yuque.com/wangyanyang/qz7fwa/xsd243 2.2 和 2.3
2. 反射实际使用:
2.1 获得类对象(三种方式)
java.lang.Class是一个类,这个类是反射操作的源头,即:所有的反射都要从类开始进行,而最关键的是这个类有三种实例化方法, 就是获得类对象。
public static void main(String[] args) {/*** 方式1: 调用Object类中的getClass()方法*/ReflectTest reflectTest = new ReflectTest();Class<? extends ReflectTest> aClass = reflectTest.getClass();System.out.println(aClass);/*** 方式2: 使用“类.class”取得*/Class<ReflectTest> aClass1 = ReflectTest.class;System.out.println(aClass1);/*** 方式3:* 调用Class类提供的一个方法--实例化Class对象* forName(String className)*/try {Class<?> aClass2 = Class.forName("com.interview.javabasic.reflection.ReflectTest");System.out.println(aClass2);} catch (ClassNotFoundException e) {e.printStackTrace();}}
2.2 反射实例化对象
拿到Class类对象, 我们可以使用反射来实例化对象. 如下是反射实例化对象的例子
public class ReflectTest2 {private Integer param;public static void main(String[] args) {ReflectTest2 reflectTest2 = new ReflectTest2();reflectTest2.normalMethod();reflectTest2.specialMethod();}public void normalMethod() {Book book = new Book();System.out.println(book.toString());}public void specialMethod() {Class<Book> bookClass = Book.class;try {Book book = bookClass.newInstance();System.out.println(book.toString());} catch (Exception e) {e.printStackTrace();}}}class Book {public Book() {System.out.println("*** Book的构造方法 ***");}@Overridepublic String toString() {return "--- 这是Book方法 ---";}}
反射在工厂模式中的应用:
public class ReflectTest3 {public static void main(String[] args) {Fruit apple = Factory.getInstance("com.interview.javabasic.reflection.Apple");apple.say("");Fruit orange = Factory.getInstance("com.interview.javabasic.reflection.Orange");orange.say("");}}interface Fruit<T> {void say(T param);}class Apple implements Fruit<String> {@Overridepublic void say(String param) {System.out.println("i am apple");}}class Orange implements Fruit<String> {@Overridepublic void say(String param) {System.out.println("i am orange");}}class Factory {public static Fruit getInstance(String className) {Fruit fruit = null;try {Class<?> aClass = Class.forName(className);fruit = (Fruit) aClass.newInstance();} catch (Exception e) {e.printStackTrace();}return fruit;}}
2.3. 反射调用构造方法 & 普通方法 & 成员
public class ReflectTest4 {public static void main(String[] args) throws Exception {try {/*** 构造函数部分*/Class<?> aClass = Class.forName("com.interview.javabasic.reflection.Phone");Constructor<?>[] constructors = aClass.getConstructors();System.out.println("获得公共的构造方法....");for (int i = 0; i < constructors.length; i++) {show(constructors[i]);}System.out.println("获取所有的构造方法...");Constructor<?>[] constructors2 = aClass.getDeclaredConstructors();for (int i = 0; i < constructors2.length; i++) {show(constructors2[i]);}System.out.println("获取多参数的, 非公共的构造函数...");Constructor<?> constructor = aClass.getDeclaredConstructor(String.class, String.class, String.class);System.out.println(constructor);System.out.println("获取无参的构造函数...");Constructor<?> constructor2 = aClass.getConstructor();System.out.println(constructor2);/*** java.lang.IllegalAccessException: Class com.interview.javabasic.reflection.ReflectTest4 can not access a member of class com.interview.javabasic.reflection.Phone with modifiers "private"*/constructor.setAccessible(true);Object iphone = constructor.newInstance("iphone", "9", "699");System.out.println("实例化对象:" + iphone);System.out.println("-----------------------------------------------");/*** 获取成员变量*/System.out.println("获取(public)变量...");Field[] fields = aClass.getFields();for (int i = 0; i < fields.length; i++) {show(fields[i]);}System.out.println("获取所有的变量...");Field[] allFields = aClass.getDeclaredFields();for (int i = 0; i < allFields.length; i++) {show(allFields[i]);}System.out.println("获取某一个public变量...");Field price = aClass.getDeclaredField("price");price.set(iphone, "6999");System.out.println("实例化对象:" + iphone);System.out.println("获取某一个private变量...");Field size = aClass.getDeclaredField("size");size.setAccessible(true);size.set(iphone, "15.6");System.out.println("实例化对象:" + iphone);System.out.println("-----------------------------------------------");/*** 获取成员方法*/System.out.println("获取(public)方法...");Method[] methods = aClass.getMethods();for (int i = 0; i < methods.length; i++) {show(methods[i]);}System.out.println("获取所有的方法...");Method[] allMethods = aClass.getDeclaredMethods();for (int i = 0; i < allMethods.length; i++) {show(allMethods[i]);}System.out.println("获取某一个public方法...");Method price2 = aClass.getDeclaredMethod("setPrice", String.class);price2.invoke(iphone, "9999");System.out.println("实例化对象:" + iphone);System.out.println("获取某一个private方法...");Method show = aClass.getDeclaredMethod("show");show.setAccessible(true);show.invoke(iphone);} catch (Exception e) {e.printStackTrace();}}private static <T> void show(T param) {System.out.println(param);}}class Phone {String name;private String size;public String price;private Phone(String name, String size, String price) {this.name = name;this.size = size;this.price = price;}public Phone() {}@Overridepublic String toString() {return "--- 这是Phone方法 ---" + this.name + "," + this.size + "," + this.price;}public void setPrice(String price) {this.price = price;}private void show() {System.out.println("Phone's size:" + size + ", only " + price + " RMB");}}
