java反射机制详解及应用

亦凉 2022-08-23 03:52 390阅读 0赞

1.如何创建Class的实例(反射的源头)

理解:

Class是一个对象,对应一个运行时类。相当于一个运行时类本身充当了Class的一个实例

过程:

源文件经过编译(javac.exe)这步,就需要进行类的加载(通过JVM的类的加载器)

记载到内存中的缓存,每一个放入缓存中的.class文件就是一个Class实例!

Java.lang.Class是反射的源头。

接下来涉及到的类都在java.lang.reflect子包下

如:Field MethodConstructor Type Package

通过Class实例调用getMethods获取所有的方法,getContructors()获取所有的Constructor

实例化Class的方法

1.调用运行时类的.class属性如:Class clazz1=Person.class; ;

2.调用类的对象,调用其getClass方法如:Person p=new Person(); Classclazz2=p.getClass();

3.调用Class静态方法forName(String className)此方法报ClassNotFoundException如:; Class clazz3=Class.forName(“1.txt”);

4.通过类的加载器:ClassLoaderloader=this.getClass().getClassLoader(); Class clazz4=loader.loadClass(“1.txt”);

2.有了Class实例之后可以做什么:(见demo)

2.1可以创建对应的运行时类的对象

2.2可以获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。如:

Method[] m1=clazz,getMethods()获取对应的运行时类(声明的Public方法),(包含父类的)

Method[] m2=clazz.getDeclaredMethod()获取对应的运行时类本身的所有公有或私有的方法(不包含父类)(任何权限)

2.3可以调用运行时类中指定的结构(某个指定的属性、方法、构造器)(见demo)

3.动态代理--反射的应用,体会反射的动态性

  1. package myNetDemo;
  2. import javax.print.attribute.standard.Sides;
  3. public class Animal {
  4. private String name;
  5. public int age;
  6. static String desc="我是一个小动物";
  7. public Animal(){
  8. super();
  9. System.out.println("测试clazz.instance()调用的初始构造器是这个!");
  10. }
  11. //test怎样调用private构造器,利用反射
  12. private Animal(String name,int age){
  13. super();
  14. this.name=name;
  15. this.age=age;
  16. }
  17. @Override
  18. public String toString() {
  19. return "Animal [name=" + name + ", age=" + age + "]";
  20. }
  21. public static void info(){
  22. System.out.println("动物");
  23. }
  24. public String getName() {
  25. return name;
  26. }
  27. public void setName(String name) {
  28. this.name = name;
  29. }
  30. //为了测试调用私有方法的方法
  31. private int getAge() {
  32. return age;
  33. }
  34. public void setAge(int age) {
  35. this.age = age;
  36. }
  37. public static String getDesc() {
  38. return desc;
  39. }
  40. public static void setDesc(String desc) {
  41. Animal.desc = desc;
  42. }
  43. public void show(String desc){
  44. System.out.println("我是一个,"+desc);
  45. }
  46. }
  47. package myNetDemo;
  48. import java.lang.reflect.Constructor;
  49. import java.lang.reflect.Field;
  50. import java.lang.reflect.Method;
  51. import org.junit.Test;
  52. public class TestReflection {
  53. // 调用指定的方法
  54. @Test
  55. public void test4() throws Exception {
  56. Class clazz = Class.forName("myNetDemo.Animal");
  57. Object obj = clazz.newInstance();
  58. Animal a = (Animal) obj;
  59. // 调用private方法
  60. Method m1 = clazz.getDeclaredMethod("getAge");
  61. m1.setAccessible(true);
  62. int age = (int) m1.invoke(a);// 方法的返回值是getAge()的返回值
  63. System.out.println(age);
  64. // 调用public方法
  65. Method m2 = clazz.getMethod("show", String.class);
  66. Object returnVal = m2.invoke(a, "小花猫");
  67. System.out.println(returnVal);//show方法的返回值,若void则为null
  68. // 调用静态方法static
  69. Method m3=clazz.getDeclaredMethod("info");
  70. m3.setAccessible(true);
  71. m3.invoke(a);
  72. m3.invoke(Animal.class);
  73. m3.invoke(null);
  74. }
  75. // 调用指定的属性
  76. @Test
  77. public void test3() throws Exception {
  78. Class clazz = Class.forName("myNetDemo.Animal");
  79. Object obj = clazz.newInstance();
  80. Animal a = (Animal) obj;
  81. // 调用私有属性
  82. Field f1 = clazz.getDeclaredField("name");
  83. f1.setAccessible(true);
  84. f1.set(a, "Jerry");
  85. // 调用共有的属性
  86. Field f2 = clazz.getField("age");
  87. f2.set(a, 9);
  88. System.out.println(a);
  89. // 要获取某个属性,是获取对象的属性
  90. System.out.println(f2.get(a));
  91. // 调用静态的属性
  92. Field f3 = clazz.getDeclaredField("desc");
  93. System.out.println(f3.get(Animal.class));
  94. System.out.println(f3.get(a));
  95. System.out.println(f3.get(null));
  96. }
  97. // 调用指定构造器调用运行时对象
  98. @Test
  99. public void test2() throws Exception {
  100. Class clazz = Animal.class;
  101. Constructor c = clazz.getDeclaredConstructor(String.class, int.class);// 调用私有方法
  102. c.setAccessible(true);// 设置访问权限
  103. Animal a = (Animal) c.newInstance("Tom", 10);
  104. System.out.println(a);
  105. }
  106. // 获取运行时对象,方式一
  107. @Test
  108. public void test1() throws Exception {
  109. Class clazz = Class.forName("myNetDemo.Animal");
  110. Object obj = clazz.newInstance();// 创建运行时对象,默认调用的是空参构造器
  111. Animal a = (Animal) obj;
  112. System.out.println(a);
  113. }
  114. }

发表评论

表情:
评论列表 (有 0 条评论,390人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java反射机制详解应用

    1.如何创建Class的实例(反射的源头) 理解: Class是一个对象,对应一个运行时类。相当于一个运行时类本身充当了Class的一个实例 过程: 源文件经过编译(j