参考资料:

  1. java反射机制深入理解剖析 https://www.w3cschool.cn/java/java-reflex.html
  2. https://dunwu.github.io/javacore/basics/java-reflection.html

    反射简介:

    主要是指程序可以访问,检测和修改本身状态或者行为的一种能力,通过反射可以调用私有方法和私有属性,大部分框架也都是运用反射原理的。java通常是先有类再有对象,有对象就可以调用方法或者属性,java中的反射其实是通过Class对象来调用类里面的方法。
    一个类有多个组成部分,例如:成员变量、方法、构造方法等,反射就是加载类,并解剖出类的各个组成部分。

反射机制主要提供以下功能:

①在运行时判断任意一个对象所属的类;

②在运行时构造任意一个类的对象;

③在运行时判断任意一个类所具有的成员变量和方法;

④在运行时调用任意一个对象的方法;

⑤生成动态代理。

类加载器的左右

image.png

  1. package com.lagou.dachang;
  2. import java.io.Serializable;
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.Field;
  5. import java.lang.reflect.InvocationTargetException;
  6. import java.lang.reflect.Method;
  7. import java.lang.reflect.Modifier;
  8. import java.util.Date;
  9. import org.junit.Test;
  10. /**
  11. * @author yumingxing
  12. * @version 1.0
  13. * @date 2022/4/18 23:30
  14. **/
  15. public class TestReflect implements Serializable {
  16. private String value;
  17. private Date date;
  18. /**
  19. * 通过对象获得完整的包名和类名
  20. */
  21. @Test
  22. public void getNameBy(){
  23. TestReflect testReflect = new TestReflect();
  24. System.out.println("testReflect.getClass().getName() = " + testReflect.getClass().getName());
  25. }
  26. /**
  27. * 实例化Class类对象
  28. */
  29. @Test
  30. public void instantiateObject(){
  31. //方式一
  32. try {
  33. Class<?> class1 = Class.forName("com.lagou.dachang.TestReflect");
  34. } catch (ClassNotFoundException e) {
  35. e.printStackTrace();
  36. }
  37. //方式二
  38. Class<? extends TestReflect> class2 = new TestReflect().getClass();
  39. //方式三
  40. Class<TestReflect> class3 = TestReflect.class;
  41. }
  42. /**
  43. * 获取一个对象的父类与实现的接口
  44. */
  45. @Test
  46. public void getSupper() throws ClassNotFoundException {
  47. Class<?> clazz = Class.forName("com.lagou.dachang.TestReflect");
  48. Class<?> superclass = clazz.getSuperclass();
  49. System.out.println("clazz的父类为:" + superclass.getName());
  50. Class<?>[] interfaces = clazz.getInterfaces();
  51. System.out.println("interfaces:");
  52. for (Class<?> anInterface : interfaces) {
  53. System.out.println(anInterface);
  54. }
  55. }
  56. /**
  57. * 通过反射实例化一个对象
  58. */
  59. @Test
  60. public void createInstance()
  61. throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
  62. Class<?> clazz = Class.forName("com.lagou.dachang.User");
  63. User user = (User) clazz.newInstance();
  64. user.setAge(18);
  65. user.setName("john");
  66. Constructor<?>[] constructors = clazz.getConstructors();
  67. for (Constructor<?> constructor : constructors) {
  68. System.out.println("constructor = " + constructor.getName());
  69. Class<?>[] parameterTypes = constructor.getParameterTypes();
  70. for (Class<?> parameterType : parameterTypes) {
  71. System.out.println("parameterType = " + parameterType.getName());
  72. }
  73. }
  74. User marry = (User) constructors[0].newInstance("marry");
  75. System.out.println("marry = " + marry);
  76. User helen = (User) constructors[1].newInstance(20, "helen");
  77. System.out.println("helen = " + helen);
  78. }
  79. /**
  80. * 通过反射获取某个类的全部属性
  81. */
  82. @Test
  83. public void getFields() throws ClassNotFoundException {
  84. Class<?> clazz = Class.forName("com.lagou.dachang.TestReflect");
  85. Field[] fields = clazz.getDeclaredFields();
  86. for (Field field : fields) {
  87. System.out.println("field.getModifiers() = " + Modifier.toString(field.getModifiers()));
  88. Class<?> type = field.getType();
  89. System.out.println(type.getName() + ":" + field.getName());
  90. }
  91. }
  92. /**
  93. * 获取某个类的全部方法
  94. */
  95. @Test
  96. public void getMethods() throws ClassNotFoundException{
  97. Class<?> clazz = Class.forName("com.lagou.dachang.TestReflect");
  98. Method[] methods = clazz.getMethods();
  99. for (Method method : methods) {
  100. System.out.println("method = " + method.getName());
  101. Class<?> returnType = method.getReturnType();
  102. System.out.println("returnType = " + returnType);
  103. System.out.println(
  104. "Modifier.toString(method.getModifiers()) = " + Modifier.toString(method.getModifiers()));
  105. Class<?>[] parameterTypes = method.getParameterTypes();
  106. for (Class<?> parameterType : parameterTypes) {
  107. System.out.println("parameterType.getName() = " + parameterType.getName());
  108. }
  109. Class<?>[] exceptionTypes = method.getExceptionTypes();
  110. for (Class<?> exceptionType : exceptionTypes) {
  111. System.out.println(exceptionType.getName());
  112. }
  113. }
  114. }
  115. /**
  116. * 通过反射调用方法
  117. */
  118. @Test
  119. public void callMethod() throws Exception{
  120. Class<?> clazz = Class.forName("com.lagou.dachang.TestReflect");
  121. Method method = clazz.getMethod("reflect1");
  122. method.invoke(clazz.newInstance());
  123. method = clazz.getMethod("reflect2", int.class, String.class);
  124. method.invoke(clazz.newInstance(),20,"张三");
  125. }
  126. /**
  127. * 通过反射操作某个类的属性
  128. */
  129. @Test
  130. public void changeField() throws Exception{
  131. Class<?> clazz = Class.forName("com.lagou.dachang.TestReflect");
  132. TestReflect testReflect = (TestReflect) clazz.newInstance();
  133. Field name = clazz.getDeclaredField("value");
  134. name.setAccessible(true);
  135. name.set(testReflect,"java反射机制");
  136. System.out.println(testReflect.getValue());
  137. }
  138. public void reflect1() {
  139. System.out.println("Java 反射机制 - 调用某个类的方法1.");
  140. }
  141. public void reflect2(int age, String name) {
  142. System.out.println("Java 反射机制 - 调用某个类的方法2.");
  143. System.out.println("age -> " + age + ". name -> " + name);
  144. }
  145. public String getValue() {
  146. return value;
  147. }
  148. public void setValue(String value) {
  149. this.value = value;
  150. }
  151. public Date getDate() {
  152. return date;
  153. }
  154. public void setDate(Date date) {
  155. this.date = date;
  156. }
  157. }
  158. class User{
  159. private int age;
  160. private String name;
  161. public User() {
  162. }
  163. public User(int age, String name) {
  164. this.age = age;
  165. this.name = name;
  166. }
  167. public User(String name) {
  168. this.name = name;
  169. }
  170. public int getAge() {
  171. return age;
  172. }
  173. public void setAge(int age) {
  174. this.age = age;
  175. }
  176. public String getName() {
  177. return name;
  178. }
  179. public void setName(String name) {
  180. this.name = name;
  181. }
  182. @Override
  183. public String toString() {
  184. return "User{" +
  185. "age=" + age +
  186. ", name='" + name + '\'' +
  187. '}';
  188. }
  189. }