加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java 通过反射和注解创建对象

发布时间:2020-12-15 07:29:00 所属栏目:Java 来源:网络整理
导读:|--要求 通过反射和注解的方式创建一个对象 |--代码 1 package com.annotation; 2 3 /** 4 * @auther::9527 5 * @Description: 元注解配合测试 6 * @program: jstl2 7 * @create: 2019-10-04 21:47 8 */ 9 public class Preson { 10 11 private String name

|--要求

通过反射和注解的方式创建一个对象

|--代码

 1 package com.annotation;
 2 
 3 /**
 4  * @auther::9527
 5  * @Description: 元注解配合测试
 6  * @program: jstl2
 7  * @create: 2019-10-04 21:47
 8  */
 9 public class Preson {
10 
11     private String name;
12     private Integer age;
13     private String sex;
14 
15     //用注解携带信息,以便反射创建对象
16     @MyAnnotation({"潘金莲","18","女"})
17     public Preson() {
18     }
19 
20     public String getName() {
21         return name;
22     }
23 
24     public void setName(String name) {
25         this.name = name;
26     }
27 
28     public Integer getAge() {
29         return age;
30     }
31 
32     public void setAge(Integer age) {
33         this.age = age;
34     }
35 
36     public String getSex() {
37         return sex;
38     }
39 
40     public void setSex(String sex) {
41         this.sex = sex;
42     }
43 
44     @Override
45     public String toString() {
46         return "Preson{" +
47                 "name=‘" + name + ‘‘‘ +
48                 ",age=" + age +
49                 ",sex=‘" + sex + ‘‘‘ +
50                 ‘}‘;
51     }
52 
53     public Preson(String name,Integer age,String sex) {
54         this.name = name;
55         this.age = age;
56         this.sex = sex;
57     }
58     //    //引入注解  此时注解不传参则表示要使用注解里面的方法对应的默认值
59 //    @MyAnnotation({"梁羽生","古龙","兰陵笑笑生","曹雪芹"})
60 //    private String name;
61 }
Preson--实体类,我们使用反射和注解操作这个类,来创建这个类的对象

 1 package com.annotation;
 2 
 3 import javax.xml.bind.Element;
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 
 9 /**
10  * @auther::9527
11  * @Description: 创建一个注解
12  * @program: jstl2
13  * @create: 2019-10-04 20:30  这两个元注解必须用大写的,因为是静态常量
14  */
15 @Target({ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR})
16 @Retention(RetentionPolicy.RUNTIME)
17 public @interface MyAnnotation {
18     //这是一个方法,当注解里面方法名只有一个的时候,那么使用注解的时候是可以不用写 方法名=“xx”的
19     //这里方法的作用主要是搬运信息
20     //此处方法的默认修饰符是public abstract
21     //这里的方法的参数可以通过default设定默认
22      String[] value() default {"李白","杜甫"};
23 }
MyAnnotation--注解类,我们使用这个注解来携带值,携带的值用于创建Preson的对象

 1 package com.annotation;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Field;
 5 import java.lang.reflect.Method;
 6 
 7 /**
 8  * @auther::9527
 9  * @Description: 读取注解信息并创建对象
10  * @program: jstl2
11  * @create: 2019-10-04 22:29
12  */
13 public class MySpring {
14     //设计一个方法,给一个类名 返回一个对象,对象内有属性值
15     public Object getBean(String className) {
16         Object obj = null;
17         try {
18             //通过传递的className获取对应的类Class
19             Class<?> clazz = Class.forName(className);
20             //通过clazz找到无参构造方法,创建一个空的对象
21             Constructor<?> con = clazz.getConstructor();
22             obj = con.newInstance();
23             //创建对象以后,将对象内的所有属性自动赋值
24             //把值存在文件里面的好处是 代码包装起来不能修改,文件可以修改    坏处是开发的时候,文件和源代码不在一起,读取和修改麻烦
25             //把值存在注解里面的好处是开发的时候方便     坏处是代码包装起来后,携带的信息不能修改
26 
27             //通过构造方法获取注解
28             MyAnnotation annotation = con.getAnnotation(MyAnnotation.class);
29             //获取注解的值  不采用简单方式,使用反射的方式获取
30             Class<? extends MyAnnotation> aClass = annotation.getClass();
31             Method value = aClass.getMethod("value");
32             String[] values = (String[]) value.invoke(annotation);
33 
34             //将values里面的值赋值给各个属性
35             //寻找属性进行赋值   获取全部属性
36             Field[] fields = clazz.getDeclaredFields();
37 // 测bug           System.out.println(fields.toString()+"*****");
38             //遍历,并操作
39             for (int i = 0; i < fields.length; i++) {
40                 //获取属性名
41                 String name = fields[i].getName();
42                 //截取字符串并操作  获得setter方法
43                 String firstLetter = name.substring(0,1).toUpperCase();
44                 String otherLetter = name.substring(1);
45                 StringBuilder setMethodName = new StringBuilder("set");
46                 setMethodName.append(firstLetter);
47                 setMethodName.append(otherLetter);
48                 //通过setter方法的名字找setter方法
49                 Class<?> filedType = fields[i].getType();
50                 Method setMethod = clazz.getDeclaredMethod(setMethodName.toString(),filedType);
51                 //运行setter方法  运行方法前,需要先将values[i]的类型转化为setter方法对应的类型
52                 //转化方法 是找到属性的类型,属性的类型里面有带String类型的构造方法,利用这个构造方法创建对象,所以创建出来的是属性类型的对象
53                 setMethod.invoke(obj,filedType.getConstructor(String.class).newInstance(values[i]));
54 
55             }
56 
57 
58         } catch (Exception e) {
59             e.printStackTrace();
60         }
61 
62 
63         return obj;
64     }
65 }
MySpring--我们在这个类里面写上反射操作注解和创建对象的方法

 1 package com.annotation;
 2 
 3 import jdk.nashorn.api.scripting.ScriptObjectMirror;
 4 
 5 /**
 6  * @auther::9527
 7  * @Description: 测试入口
 8  * @program: jstl2
 9  * @create: 2019-10-04 23:54
10  */
11 public class TestMain {
12     public static void main(String[] args) {
13         //实例化MySpring
14         MySpring mySpring = new MySpring();
15         //由MySpring 的getBean方法创建对象
16         Preson preson = (Preson) mySpring.getBean("com.annotation.Preson");
17         //打印对象,看是否OK
18         System.out.println(preson.toString());;
19     }
20 }
测试入口

|--运行结果

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读