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

Posted twuxian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
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 }
测试入口

|--运行结果

技术图片

 

以上是关于java 通过反射和注解创建对象的主要内容,如果未能解决你的问题,请参考以下文章

注解与反射-复习

java反射与注解结合使用(根据传入对象输出查询sql)

反射读取注解信息

Java之枚举注解反射

Java利用Java的注解和反射实现一个"低配版"的依赖注入

java反射和注解