Java 反射

  1 //-- 练习使用反射技术获取带有@Controller 标注的方法,并执行它。
  2 
  3 import java.lang.reflect.*;
  4 /**
  5  * 设计模式+反射+注解(xml) Spring Hibernate MyBatis
  6  * 反射机制
  7  * :Java语言提供的一种可以窥探class类里的属性和方法技术。
  8  * 原理:
  9  */
 10 public class Demo03 {
 11     public static void main(String[] args) throws Exception {
 12         //--  1.拿到Student类的类对象,也就是那个Class类型的对象
 13         //--  2. 获取的方式:方式一:
 14         Class c1 = Class.forName("day02.Student");//包+类名
 15         //--                方式二:
 16         Class c2 = Student.class;
 17         //System.out.println(c1 == c2);
 18         //-- 问题一: Student类什么时候获取的:类加载
 19         //-- 问题二: 什么时候类会被加载:
 20         //Student stu;不会加载Student(可以利用静态代码块模拟看)
 21         //--  3. 使用 Class 对象获取类的属性
 22         Field[] fs = c1.getDeclaredFields();
 23         
 24         //-- 4. 遍历所有的属性,进行输出
 25         for (Field field : fs) {
 26             System.out.println(field.getType() + " " + field.getName());
 27         }
 28         
 29         //-- 5. 使用 Class 对象获取类的方法
 30         Method[] methods = c1.getDeclaredMethods();
 31         for (Method method : methods) {
 32             System.out.println(method.getReturnType() + " " +method.getName());
 33         }
 34     }
 35 }
 36 //-- 每个类里面有一个Class类型的属性,这个类类型的对象可以窥探本类的一切。
 37 //-- 而且该类类型的对象对于某个类来说,有且仅有一个。
 38 class Student{
 39     //-- 属性
 40     //默认带有 Student this; Object super; static Class c(通过这个属性进行反射);    
 41     String name;
 42     //-- 方法
 43     public void study() {
 44         System.out.println("we love study");
 45     }
 46     static{
 47         System.out.println("Student 被加载。。。");
 48     }
 49 }
 50 
 51 /**
 52  * 反射工具类
 53  *
 54  */
 55 public class ReflectUtil {
 56     /**
 57      * 获取某个类的某个方法
 58      */
 59     public static Method getMethod(String className, String methodName) {
 60         Class c;
 61         try {
 62             c = Class.forName(className);
 63         } catch (ClassNotFoundException e) {
 64             return null;
 65         }
 66         Method[] ms = c.getDeclaredMethods();
 67         for (Method method : ms) {
 68             if (method.equals(methodName)) {
 69                 return method; 
 70             }
 71         }
 72         return null;
 73     } 
 74     
 75     /**
 76      * @param className
 77      * @param annotationName
 78      * @return Object
 79      *  使用反射技术获取带有@Controller 标注的方法。框架的原理。
 80      */
 81     
 82     public static Object excuteMethodWithAnnotation(String className,String annotationName) throws Exception {
 83         //-- 1. 获取类类型对象
 84         Class c = null;
 85         Object o = null;
 86         try {
 87             c = Class.forName(className);
 88             //-- 2 . 创建一个类对象对应得类得对象
 89             o = c.newInstance(); //多态
 90         } catch (Exception e) {
 91             e.printStackTrace();
 92         }
 93         
 94         //-- 3. 获取该类的所有的方法
 95         Method[] ms = c.getDeclaredMethods();
 96         //-- 4. 遍历方法
 97         for (Method method : ms) {
 98             //-- 5. 判断某方法是否被我们给定的标注所标注,若有则执行
 99             Annotation[] ans = method.getDeclaredAnnotations();
100             for (Annotation an : ans) {
101                 //-- 6.判断哪个标注是我们给定的标注
102                 if (an.annotationType().getSimpleName().equals(annotationName)){
103                     //-- 7. 执行该方法
104                     Object result = method.invoke(o, null);//-- o 代表实列对象,args代表调用的方法的参数。
105                     return result;
106                 }
107             }
108         }
109         return null;
110     }
111     
112 }

写个标注@calculator,再利用反射写一个方法,
 这个方法用于计算某个加有@calculator标注的类的方法的运行时间(耗时)

 1 package day02.util;
 2 
 3 import java.lang.annotation.*;
 4 import java.lang.reflect.*;
 5 
 6 public class 作业 {
 7     public static void main(String[] args) throws Exception {
 8         
 9         String calculatorMethod = ReflectUtil2.calculatorMethod("day02.util.Test00000", "calculator");
10         System.out.println(calculatorMethod);
11         
12     }
13 }
14 
15 @Target({ElementType.TYPE,ElementType.METHOD})
16 @Retention(RetentionPolicy.RUNTIME)
17 @interface calculator{
18     String value() default "计算方法时间";
19 }
20 
21 class ReflectUtil2{
22     public static String calculatorMethod(String className, String annotationName) throws Exception {
23         Class c = Class.forName(className);
24         Object obj = c.newInstance();
25         
26         Method[] methods = c.getDeclaredMethods();
27         for (Method method : methods) {
28             Annotation[] annotations = method.getDeclaredAnnotations();
29             for (Annotation annotation : annotations) {
30                 if(annotation.annotationType().getSimpleName().equals(annotationName)) {
31                     //long startTimeMillis = System.currentTimeMillis();
32                     long startTimeMillis = System.nanoTime();
33                     method.invoke(obj, null);
34                     //long endTimeMillis = System.currentTimeMillis()-startTimeMillis;
35                     long endTimeMillis = System.nanoTime()-startTimeMillis;
36                     return endTimeMillis+"ns";
37                 }
38             }
39         }
40         
41         return null;
42     }
43 }
44 class Test00000 {
45     
46     @calculator
47     public void test() {
48         for(int i = 0; i <= 1000; i++) {
49             //System.out.print(i);
50             if(i%100 == 0) {
51                 //System.out.println();
52             }
53         }
54     }
55 }

 

posted @ 2019-10-17 23:28  张泽  阅读(150)  评论(0编辑  收藏  举报