[关闭]
@linux1s1s 2019-02-15T21:03:46.000000Z 字数 5854 阅读 1917

Java 反射基础

Java 2015-11


Java 反射的基本概念这里不做赘述,直接上Demo。

Person类

  1. package com.linroid.refact.test;
  2. public class Person {
  3. private int age;
  4. private String name;
  5. public Person() {
  6. }
  7. public Person(int age, String name) {
  8. this.age = age;
  9. this.name = name;
  10. }
  11. public int getAge() {
  12. return age;
  13. }
  14. public void setAge(int age) {
  15. this.age = age;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. }

PersonSub子类

  1. package com.linroid.refact.test;
  2. public class PersonSub extends Person implements Refector {
  3. public PersonSub() {
  4. super();
  5. }
  6. @Override
  7. public void refector() {
  8. System.out.println("This refector method come from PersonSub.refector()");
  9. }
  10. }

Refector接口

  1. package com.linroid.refact.test;
  2. public interface Refector {
  3. public void refector();
  4. }

测试用例CommonCase类

  1. package com.linroid.refact.test;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.Modifier;
  7. public class CommonCase {
  8. public static void main(String[] args) {
  9. showPackageAndName();
  10. System.out.println("===============================================");
  11. obtainClassRefine();
  12. System.out.println("===============================================");
  13. newInstanceWithNoParam();
  14. System.out.println("===============================================");
  15. newInstanceWithParam();
  16. System.out.println("===============================================");
  17. modifiedDeclaredField();
  18. System.out.println("===============================================");
  19. useDeclaredMethod();
  20. System.out.println("===============================================");
  21. showObjectInfo();
  22. }
  23. // 通过一个对象获得完整的包名和类名,从这个demo中可以得出所有类的实例其实就是Class的实例
  24. private static void showPackageAndName() {
  25. Person person = new Person();
  26. System.out.println(person.getClass().getName());
  27. }
  28. // 通过完整包名直接获得实例,推荐使用这种方式
  29. private static Class<?> obtainClassRefine(String packageName) {
  30. if (packageName == null || packageName.isEmpty()) {
  31. return null;
  32. }
  33. Class<?> person = null;
  34. try {
  35. person = Class.forName(packageName);
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }
  39. System.out.println("类名称: " + person.getName());
  40. return person;
  41. }
  42. private static Class<?> obtainClassRefine() {
  43. return obtainClassRefine("com.linroid.refact.test.Person");
  44. }
  45. // 接下来获得了Class实例以后,就要初始化这个实例
  46. private static void newInstanceWithNoParam() {
  47. Class<?> classPerson = obtainClassRefine();
  48. Person person = null;
  49. if (classPerson != null) {
  50. // 由于这里不能带参数,所以你要实例化的这个类Person,一定要有无参构造函数 ,如果没有无参数的构造器,就一定会抛异常
  51. try {
  52. person = (Person) classPerson.newInstance();
  53. person.setAge(20);
  54. person.setName("Nacy");
  55. System.out.println("Persion: name is " + person.getName() + " age is " + person.getAge());
  56. } catch (InstantiationException e) {
  57. e.printStackTrace();
  58. } catch (IllegalAccessException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. }
  63. // 接着上面的例子,如果没有无参数构造器,会发生什么,该如何应对?
  64. private static void newInstanceWithParam() {
  65. Class<?> classPerson = obtainClassRefine();
  66. Person person1 = null;
  67. Person person2 = null;
  68. if (classPerson != null) {
  69. // 仅仅获取Public构造器,其他包权限、private权限以及protected权限不能获取。换句话说,如果是非Public权限的构造器,通过下面这种反射办法是不能解决问题
  70. Constructor<?>[] constructor = classPerson.getConstructors();
  71. if (constructor.length >= 2) {
  72. try {
  73. person1 = (Person) constructor[0].newInstance();
  74. person1.setAge(21);
  75. person1.setName("Gracy");
  76. person2 = (Person) constructor[1].newInstance(22, "Brala");
  77. System.out.println("Persion: name is " + person1.getName() + " age is " + person1.getAge());
  78. System.out.println("Persion: name is " + person2.getName() + " age is " + person2.getAge());
  79. } catch (InstantiationException e) {
  80. e.printStackTrace();
  81. } catch (IllegalAccessException e) {
  82. e.printStackTrace();
  83. } catch (IllegalArgumentException e) {
  84. e.printStackTrace();
  85. } catch (InvocationTargetException e) {
  86. e.printStackTrace();
  87. }
  88. }
  89. }
  90. }
  91. // 获得构造器以后可以构造实例,在构造实例的同时会初始化成员变量,如果不满意,也可以直接通过反射获取成员变量,然后直接赋值改变即可
  92. private static void modifiedDeclaredField() {
  93. Class<?> classPerson = obtainClassRefine();
  94. Person person = null;
  95. if (classPerson != null) {
  96. try {
  97. person = (Person) classPerson.newInstance();
  98. Field name = classPerson.getDeclaredField("name");
  99. if (name != null) {
  100. name.setAccessible(true);
  101. name.set(person, "Durk");
  102. }
  103. Field age = classPerson.getDeclaredField("age");
  104. if (age != null) {
  105. age.setAccessible(true);
  106. age.set(person, 12);
  107. }
  108. System.out.println("Persion: name is " + person.getName() + " age is " + person.getAge());
  109. } catch (NoSuchFieldException e) {
  110. e.printStackTrace();
  111. } catch (SecurityException e) {
  112. e.printStackTrace();
  113. } catch (InstantiationException e1) {
  114. e1.printStackTrace();
  115. } catch (IllegalAccessException e1) {
  116. e1.printStackTrace();
  117. }
  118. }
  119. }
  120. // 接下来看看反射最有用处的地方,通过Java反射机制调用类方法
  121. private static void useDeclaredMethod() {
  122. Class<?> classPerson = obtainClassRefine("com.linroid.refact.test.PersonSub");
  123. Person person = null;
  124. if (classPerson != null) {
  125. try {
  126. person = (Person) classPerson.newInstance();
  127. Method refector = classPerson.getMethod("refector");
  128. if (refector != null) {
  129. refector.invoke(person);
  130. }
  131. } catch (InstantiationException e) {
  132. e.printStackTrace();
  133. } catch (IllegalAccessException e) {
  134. e.printStackTrace();
  135. } catch (NoSuchMethodException | SecurityException e) {
  136. e.printStackTrace();
  137. } catch (IllegalArgumentException | InvocationTargetException e) {
  138. e.printStackTrace();
  139. }
  140. }
  141. }
  142. // 获取类的基本信息,比如继承的接口,父类,函数信息,成员信息,类型等
  143. private static void showObjectInfo() {
  144. Class<?> classPerson = obtainClassRefine("com.linroid.refact.test.PersonSub");
  145. if (classPerson != null) {
  146. // 获取父类名
  147. Class<?> superClass = classPerson.getSuperclass();
  148. System.out.println("Persion: Super class name is " + superClass.getName());
  149. // 获取类的成员变量
  150. Field[] fields = classPerson.getFields();
  151. int fieldSize = 0;
  152. if (fields != null && (fieldSize = fields.length) > 0) {
  153. for (int i = 0; i < fieldSize; i++) {
  154. System.out.println("类中的成员: " + fields[i]);
  155. }
  156. }
  157. // 获取类的方法
  158. Method[] methods = classPerson.getDeclaredMethods();
  159. int methodSize = 0;
  160. if (methods != null & (methodSize = methods.length) > 0) {
  161. for (int i = 0; i < methodSize; i++) {
  162. System.out.println("函数名:" + methods[i].getName());
  163. System.out.println("函数返回类型:" + methods[i].getReturnType());
  164. System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers()));
  165. System.out.println("函数代码写法: " + methods[i]);
  166. }
  167. }
  168. // 获取类实现的接口, 是不是看到多重继承的影子了\(^o^)/~
  169. Class<?>[] implementsClass = classPerson.getInterfaces();
  170. int implementsSize = 0;
  171. if (implementsClass != null && (implementsSize = implementsClass.length) > 0) {
  172. for (int i = 0; i < implementsSize; i++) {
  173. System.out.println("实现的接口类名: " + implementsClass[i].getName());
  174. }
  175. }
  176. }
  177. }
  178. }

运行结果

此处输入图片的描述

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注