[关闭]
@frank-shaw 2015-10-29T03:09:52.000000Z 字数 4175 阅读 1568

Java中的反射

java.类加载


API中,关于java.lang.reflect 的描述:
提供类和接口,以获得关于类和对象的反射信息。在安全限制内,反射允许编程访问关于加载类的字段、方法和构造方法的信息,并允许使用反射字段、方法和构造方法对其底层对等项进行操作。

是否允许修改类的相关信息呢?不可能吧,类在class文件中早已经被固定住了。

可以实例化一个类,进而可以修改这个对象的字段与属性等。这是自己写的程序,日后的你是否还看得懂呢?一个一个实例来测试实验,进而有很多代码已经被注释。

  1. /**
  2. *
  3. */
  4. package reflect;
  5. import java.lang.reflect.*;
  6. /**
  7. * @author xiao
  8. *
  9. */
  10. public class TestReflect {
  11. /**
  12. * @param args
  13. */
  14. public static void main(String[] args) {
  15. // TODO Auto-generated method stub
  16. Dog d = new Dog();
  17. // //获取类的三种方法:
  18. // // 1.对象的getClass()方法 2.类.class 3.Class.forName(类名称)
  19. // System.out.println(a1.getClass().getName());
  20. // System.out.println(Dog.class.getName());
  21. //
  22. // Class<?> dog1 = null;
  23. // try{
  24. // dog1 = Class.forName("reflect.Dog");//这种方法必然产生异常
  25. // } catch(Exception e){
  26. // e.printStackTrace();
  27. // }
  28. // System.out.println(dog1.getName());
  29. /*
  30. * 通过class来实例化来获取其他的对象
  31. * 在使用Class实例化其他类的对象的时候,一定要自己定义一个无参数的构造函数
  32. */
  33. // Class<?> dog1 = Dog.class;
  34. // Dog d2 = null;
  35. // try{
  36. // d2 = (Dog) dog1.newInstance();
  37. // } catch(Exception e){
  38. // e.printStackTrace();
  39. // }
  40. // d2.setAge(3);
  41. // System.out.println(d2);
  42. /*
  43. * 通过class来获取其他类的构造方法
  44. */
  45. // Class<?> cat1 = Cat.class;
  46. // Constructor<?>[] cons = cat1.getConstructors();
  47. // for(Constructor<?> con : cons)
  48. // System.out.println(con);
  49. //
  50. // Cat cat2 = null;
  51. // try{
  52. // cat2 = (Cat) cons[0].newInstance("kitty");
  53. // }catch(Exception e){//catch多个异常的时候,范围小的要在前面,最后才是Exception
  54. // e.printStackTrace();
  55. // }
  56. // System.out.println(cat2);
  57. //
  58. /*
  59. * 通过class来获取其他类的接口信息
  60. *
  61. */
  62. // Class<?> cat1 = Cat.class;
  63. // Class<?>[] inters = cat1.getInterfaces();
  64. // System.out.println(cat1.getSimpleName()+"类实现的接口有:");
  65. // for(Class<?> inter :inters)
  66. // System.out.println(" "+inter.getSimpleName());
  67. //
  68. /*
  69. * 通过class来获取其他类的字段信息
  70. * getDeclaredFields()表示获取的是本类字段的所有信息
  71. * getFields()表示获取的是父类或者接口字段的public范围的信息(注意默认权限并不是public)
  72. */
  73. // Class<?> cat1 = Cat.class;
  74. // Field[] fieldSelf = cat1.getDeclaredFields();
  75. // for(Field f : fieldSelf){
  76. // System.out.println(f.getName());
  77. // }
  78. /*
  79. * 在上一要求的基础上
  80. * 通过class来修改其他类的字段信息
  81. * 如果该字段信息是该类的private变量,那么需要设置
  82. *
  83. */
  84. Class<?> dog3 = Dog.class;
  85. try{
  86. Dog d3 =(Dog) dog3.newInstance();
  87. //Dog d3 = new Dog();
  88. Field f3 = null;
  89. try{//原来还可尝试多层嵌套
  90. f3 = dog3.getDeclaredField("name");//获取某一个字段信息
  91. //修改字段信息
  92. f3.setAccessible(true);//针对的是类中的私有字段
  93. f3.set(d3, "aFu");
  94. System.out.println(d3.toString());
  95. }catch(Exception e){
  96. e.printStackTrace();
  97. }
  98. }catch(Exception e){
  99. e.printStackTrace();
  100. }
  101. /*
  102. *
  103. *通过class来获取其他类的方法,并且实例化该类(通过newInstance()方法)以调用该方法
  104. *getMethod(str,args)第一个表示方法名称,字符串;第二个表示输入参数类型,可以是多个
  105. *Class类型组成的数组,下面这个例子就是两个不同类型参数组成的数组。在真实传入的时候
  106. *需要编程Object数组,因为两个参数类型不一样,只能用Object数组来装。
  107. *
  108. */
  109. // Class<?> cat1 = Cat.class;
  110. // try{
  111. // //设置Class数组在getMethod()方法中作为参数
  112. // Class[] arges = new Class[2];
  113. // arges[0] = String.class;
  114. // arges[1] = int.class;
  115. //
  116. // //设置Object[]数组在invoke()方法中作为参数
  117. // Object[] ars = new Object[2];
  118. // ars[0] = "kitty";
  119. // ars[1] = 3;
  120. //
  121. // //返回值是Method类
  122. // Method m1 = null;
  123. // m1 = cat1.getMethod("sleep",arges);
  124. // m1.invoke(cat1.newInstance(),ars);
  125. // //输出:kitty正在睡觉···3
  126. //
  127. // }catch(Exception e){
  128. // e.printStackTrace();
  129. // }
  130. }
  131. }
  132. ========================================
  133. public interface Animal {
  134. int data = 0;//接口中的变量一定是public static final
  135. void call(String str);
  136. String eat();
  137. }
  138. =========================================
  139. public class Dog implements Animal {
  140. int age;
  141. private String name;
  142. //constructor
  143. public Dog(){
  144. }
  145. public Dog(int age){
  146. this.age = age;
  147. }
  148. public Dog(String name){
  149. this.name = name;
  150. }
  151. public Dog(int age, String name) {
  152. this.age = age;
  153. this.name = name;
  154. }
  155. //getter and setter
  156. public int getAge() {
  157. return age;
  158. }
  159. public void setAge(int age) {
  160. this.age = age;
  161. }
  162. public String getName() {
  163. return name;
  164. }
  165. public void setName(String name) {
  166. this.name = name;
  167. }
  168. @Override
  169. public void call(String str) {
  170. System.out.println("汪汪···");
  171. }
  172. @Override
  173. public String eat() {
  174. // TODO Auto-generated method stub
  175. return "小骨头···";
  176. }
  177. @Override
  178. public String toString() {
  179. // TODO Auto-generated method stub
  180. return "age:" + age+" || "+"name:"+name;
  181. }
  182. }
  183. ======================================
  184. public class Cat implements Animal {
  185. public int age;
  186. String name;
  187. //constructor
  188. public Cat(){
  189. }
  190. public Cat(int age){
  191. this.age = age;
  192. }
  193. public Cat(String name){
  194. this.name = name;
  195. }
  196. public Cat(int age, String name) {
  197. super();
  198. this.age = age;
  199. this.name = name;
  200. }
  201. //getter and setter
  202. public int getAge() {
  203. return age;
  204. }
  205. public void setAge(int age) {
  206. this.age = age;
  207. }
  208. public String getName() {
  209. return name;
  210. }
  211. public void setName(String name) {
  212. this.name = name;
  213. }
  214. @Override
  215. public void call(String str) {
  216. System.out.println(str+" 喵喵···");
  217. }
  218. @Override
  219. public String eat() {
  220. return "好吃的鱼···";
  221. }
  222. @Override
  223. public String toString() {
  224. return "age:" + age+" || "+"name:"+name;
  225. }
  226. public void sleep(String str, int cnt){
  227. System.out.println(str+"正在睡觉···"+cnt);
  228. }
  229. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注