码迷,mamicode.com
首页 > 其他好文 > 详细

【回归系列】反射

时间:2018-07-06 12:19:12      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:比较   nts   扩展   als   not   access   boot   获取   ssi   

反射就是动态加载对象,并对对象进行剖析。在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能成为Java反射机制。

 

一、基本操作

 1 package com.slp.springbootelasticsearch.test;
 2 
 3 import java.lang.reflect.Field;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Modifier;
 6 
 7 /**
 8  * @author sanglp
 9  * @create 2018-07-05 17:30
10  * @desc 测试类
11  **/
12 public class Student {
13     private long id;
14     private String name;
15 
16     public long getId() {
17         return id;
18     }
19 
20     public void setId(long id) {
21         this.id = id;
22     }
23 
24     public String getName() {
25         return name;
26     }
27 
28     public void setName(String name) {
29         this.name = name;
30     }
31 
32 
33     public static  void  main(String[] args){
34         try {
35             //初始化指定的类
36             Class<?> claz= Class.forName("com.slp.springbootelasticsearch.test.Student");
37             //获取类中所有的方法(包括其继承类的方法)
38             Method[] methods = claz.getMethods();
39             for(Method method :methods){
40                 System.out.println("方法名:"+method.getName());
41             }
42             System.out.println("------------------");
43             //获取加载类中的方法,不要父类的方法
44             methods = claz.getDeclaredMethods();
45             for(Method method :methods){
46                 System.out.println("方法名:"+method.getName());
47                 System.out.println("方法返回类型:"+method.getReturnType().getName());
48                 System.out.println("方法修饰符:"+ Modifier.toString(method.getModifiers()));
49                 System.out.println("方法参数信息:"+ method.getParameters());
50                 System.out.println("方法上的注解:"+method.getAnnotations());
51             }
52             System.out.println("--------------------");
53             //使用反射调用方法 通过class的newInstance()方法构造一个Student对象,然后调用getName()方法,这个时候输出的是null,然后通过方法名获取到setName方法,通过invoke调用方法,传入参数,然后调用getName()方法就可以看到输出的就是我们设置的值“大小”
54             Student stu = (Student)claz.newInstance();
55             System.out.println(stu.getName());
56             Method method = claz.getMethod("setName",String.class);
57             method.invoke(stu,"大小");
58             System.out.println(stu.getName());
59             System.out.println("--------------------");
60             //获取类中所有属性 getFields只能获取public的属性,包括父类的
61             Field[]  fields = claz.getFields();
62             for(Field field:fields){
63                 System.out.println("属性名"+field.getName());
64             }
65             //获取自己声明的各种字段要使用getDeclaredFields()
66             fields = claz.getDeclaredFields();
67             for(Field field:fields){
68                 System.out.println("属性名"+field.getName());
69                 System.out.println("属性类型"+field.getType().getName());
70                 System.out.println("属性修饰符"+Modifier.toString(field.getModifiers()));
71                 System.out.println("属性上的注解"+field.getAnnotations());
72             }
73             //操作属性
74             Field field = claz.getDeclaredField("name");
75             //取消java控制权限,让访问时可以访问私有变量
76             field.setAccessible(true);
77             System.out.println(field.get(stu));
78             field.set(stu,"大小");
79             System.out.println(field.get(stu));
80         } catch (Exception e) {
81             e.printStackTrace();
82         }
83 
84     }
85 }

输出:

 1 方法名:main
 2 方法名:getName
 3 方法名:getId
 4 方法名:setName
 5 方法名:setId
 6 方法名:wait
 7 方法名:wait
 8 方法名:wait
 9 方法名:equals
10 方法名:toString
11 方法名:hashCode
12 方法名:getClass
13 方法名:notify
14 方法名:notifyAll
15 ------------------
16 方法名:main
17 方法返回类型:void
18 方法修饰符:public static
19 方法参数信息:[Ljava.lang.reflect.Parameter;@49097b5d
20 方法上的注解:[Ljava.lang.annotation.Annotation;@37a71e93
21 方法名:getName
22 方法返回类型:java.lang.String
23 方法修饰符:public
24 方法参数信息:[Ljava.lang.reflect.Parameter;@7e6cbb7a
25 方法上的注解:[Ljava.lang.annotation.Annotation;@37a71e93
26 方法名:getId
27 方法返回类型:long
28 方法修饰符:public
29 方法参数信息:[Ljava.lang.reflect.Parameter;@7c3df479
30 方法上的注解:[Ljava.lang.annotation.Annotation;@37a71e93
31 方法名:setName
32 方法返回类型:void
33 方法修饰符:public
34 方法参数信息:[Ljava.lang.reflect.Parameter;@7106e68e
35 方法上的注解:[Ljava.lang.annotation.Annotation;@37a71e93
36 方法名:setId
37 方法返回类型:void
38 方法修饰符:public
39 方法参数信息:[Ljava.lang.reflect.Parameter;@7eda2dbb
40 方法上的注解:[Ljava.lang.annotation.Annotation;@37a71e93
41 --------------------
42 null
43 大小
44 --------------------
45 属性名id
46 属性类型long
47 属性修饰符private
48 属性上的注解[Ljava.lang.annotation.Annotation;@37a71e93
49 属性名name
50 属性类型java.lang.String
51 属性修饰符private
52 属性上的注解[Ljava.lang.annotation.Annotation;@37a71e93
53 大小
54 大小

二、优点和缺点

1、优点

反射提高了程序的灵活性和扩展性,在底层框架中用的比较多,业务层面的开发过程中尽量少用。

2、缺点

反射是一种解释操作,用于字段和方法接入时要远慢于直接代码。

程序逻辑有影响。

 

【回归系列】反射

标签:比较   nts   扩展   als   not   access   boot   获取   ssi   

原文地址:https://www.cnblogs.com/dream-to-pku/p/9272835.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!