在 Java 框架中, 经常会使用注解, 而且还可以省很多事, 来了解下自定义注解.
注解是一种能被添加到 java 代码中的元数据, 类, 方法, 变量, 参数和包都可以用注解来修饰. 注解对于它所修饰的代码并没有直接的影响
先写一个自己的注解类
- @Documented // 会被 javadoc 命令识别
- @Retention(RetentionPolicy.RUNTIME) // 相当于作用时期, 比如: 运行期, 编译期
- @Target({ElementType.METHOD}) // 相当于作用域, 比如方法, 类
- public @interface MyValue {
- String value();
- // 也可以这么写, 就是说, 它的默认值是 hello
- //String value() default "hello";
- }
然后解析上边用到的那两个类:
- public enum RetentionPolicy {
- SOURCE,
- CLASS,
- RUNTIME
- }
- public enum ElementType {
- /** Class, interface (including annotation type), or enum declaration */
- TYPE,
- FIELD,
- METHOD,
- PARAMETER,
- CONSTRUCTOR,
- LOCAL_VARIABLE,
- ANNOTATION_TYPE,
- PACKAGE
- }
可以看到, 是两个枚举类, 也就是我们自定义的注解有一定的时间和空间作用域.
好了, 我们的自定义注解已经完成了 (对的, 自定义注解就上边那一段代码), 那我们就来看看要怎么有用呢? 很容易啊, 就和其他的注解一样, 写在我们要用到的地方就好了.(对的, 我确定不是在开玩笑)
- public class Person {
- @MyValue(value="张三")
- private String name;
- /*
- 为什么要写 setter 和 getter, 很快你就会知道
- */
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
然后我们在其他地方去拿
- Person person = new Person();
- System.out.println(person.getName());//null
- // 这就很难受, 按道理来说, 不是应该是张三吗?
大家都知道, 像 Spring 这种框架都是通过反射来实现的, 我们就模拟一个 "编译类", 我们是在属性上用的注解, 所以就先用反射来拿到类的所有属性
- public static void main(String[] args) throws NoSuchFieldException {
- Person person = new Person();
- // 按理来说, 我们是拿到这个 Person.class 的所有的属性, 然后遍历, 来挨个注入, 但是这里我们明明确我们的属性名, 所以就简单化了
- Field field = Person.class.getDeclaredField("name");
- MyValue annotation = field.getAnnotation(MyValue.class);// 拿到注解类
- String name = annotation.value();// 这个 value() 就是我们在 MyValue 类中的的属性
- // 然后我们就注入到这个类中, 这时就用到了 setter 方法
- person.setName(name);
- System.out.println("通过自定义注解后的 person 的 name 是:" + person.getName());
- }
是的, 这样我们就通过了自定义注解给 Person 注入了一个 name 属性, 但是在实际运用中不可能这么复杂, 这只是入门了一下, 我们可以将这个 "模拟的编译类" 组装成一个工具类, 以便我们在实际中运用.
来源: https://www.cnblogs.com/Lyn4ever/p/11594533.html