java注解开发

一、什么是注解

        Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
        Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。

二、注解的分类

注解分类
由上图可知:注解共分为:标记注解、标准元注解、一般注解三类。
【注】:Deprecated注解,除了多个删除线,并没有什么拦截功能。

三、标准元注解详解

        标准元注解是自定义注解的注解,主要包含4个,都位于java.lang.annotation包中,我们创建自定义注解时会用到4个标准元注解。它们的名称以及含义如下:

  1. @Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。是一个标记注解,没有成员。

  2. @Inherited:是否允许子类继承该注解

  3. @Retention:定义了该注解的生命周期:某些注解仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为注解与class在使用上是被分离的)。使用这个元注解可以对自定义注解的“生命周期”进行限制。
    生命周期策略枚举
    RetentionPolicy.RUNTIME注解会在class字节码文件中存在,在运行时可以通过反射获取到。
    RetentionPolicy.CLASS 默认的保留策略,在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
    RetentionPolicy.SOURCE 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。

  4. @Target:说明了注解所修饰的对象范围:注解可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)
    修饰范围枚举
    ElementType.CONSTRUCTOR 作用于构造器
    ElementType.FIELD 作用于域/属性
    ElementType.LOCAL_VARIABLE 用于描述局部变量
    ElementType.METHOD 作用于方法
    ElementType.PACKAGE 用于描述包
    ElementType.PARAMETER 用于描述参数
    ElementType.TYPE 用于描述类、接口(包括注解类型) 或enum声明,最常用
    ElementType.ANNOTATION_TYPE 另一个注解

  5. @Repeatable:Repeatable 自然是可重复的意思。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。什么样的注解会多次应用呢?通常是注解的值可以同时取多个。举个例子,一个人他既是程序员又是产品经理,同时他还是个画家。

四、自定义注解

1、自定义类注解ClassAnnotation

package com.xsl;

import java.lang.annotation.*;

/**
 * @Description 自定义类注解
 * @Author xsl
 * @Date 2020/1/8 11:58
 **/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassAnnotation{
    String name() default "defaultService";
    String version() default "1.0.0.RELEASE";
}

2、自定义域注解FieldAnnotation

package com.xsl;

import java.lang.annotation.*;

/**
 * @Description 自定义域注解
 * @Author xsl
 * @Date 2020/1/8 11:58
 **/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation {
    String name() default "defaultName";
    String value() default "defaultValue";
}

3、自定义方法注解枚举MethodTypeEnum

package com.xsl;

/**
 * @Description 方法类型枚举
 * @Author xsl
 * @Date 2020/1/8 11:58
 **/

public enum MethodTypeEnum {
    TYPE1,TYPE2
}

4、自定义方法注解MethodAnnotation

package com.xsl;

import java.lang.annotation.*;

/**
 * @Description 自定义域注解
 * @Author xsl
 * @Date 2020/1/8 11:58
 **/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodAnnotation {
    String name() default "defaultName";
    MethodTypeEnum type() default MethodTypeEnum.TYPE1;
}

五、测试注解

1、测试注解类

package com.xsl;

/**
 * @Description 注解测试类
 * @Author xsl
 * @Date 2020/1/8 11:58
 **/
@ClassAnnotation(name = "personBean",version = "1.2.0.RELEASE")
public class Person {
    @FieldAnnotation(name = "desc",value = "my personal annotation")
    private String desc;
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    @MethodAnnotation(name="sayHello", type = MethodTypeEnum.TYPE2)
    public void sayHello() {
        System.out.println("Hello Annotation!");
    }
}

2、测试类

package com.xsl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Description 测试类
 * @Author xsl
 * @Date 2020/1/8 13:02
 **/
public class TestMyAnnotation {

    private static Person person = new Person();

    public static void main(String[] args) throws Exception {
        testClassAnnotation();
        System.out.println("-----------------------------------------");
        testFiledAnnotation();
        System.out.println("-----------------------------------------");
        testMethodAnnotation();

    }

    private static void testClassAnnotation(){
        Class<? extends Person> clazz = person.getClass();
        //因为注解是作用于类上面的,所以可以通过isAnnotationPresent来判断是否是一个具有指定注解的类
        if(clazz.isAnnotationPresent(ClassAnnotation.class)) {
            System.out.println("This is a class with annotation ClassAnnotation!");
            //通过getAnnotation可以获取注解对象
            ClassAnnotation annotation = clazz.getAnnotation(ClassAnnotation.class);
            if(null != annotation) {
                System.out.println("BeanName = " + annotation.name());
                System.out.println("BeanVersion = " + annotation.version());
            }else{
                System.out.println("the annotation that we get is null");
            }
        }else{
            System.out.println("This is not the class that with ClassAnnotation");
        }
    }


    private static void testFiledAnnotation() throws Exception {
        Class<?> clazz = person.getClass();
        //因为是注解到Field上的,所以首先要获取这个字段
        Field field = clazz.getDeclaredField("desc");
        //判断这个Field上是否有这个注解
        if(field.isAnnotationPresent(FieldAnnotation.class)) {
            System.out.println("===This is a field with annotation:FieldAnnotation!===");
            //如果有这个注解,则获取注解类
            FieldAnnotation annotation = field.getAnnotation(FieldAnnotation.class);
            if(null != annotation){
                System.out.println("before set the value is:" + person.getDesc());
                //通过反射给私有变量赋值
                field.setAccessible(true);
                field.set(person, annotation.value());
                System.out.println("after set the value is:" + person.getDesc());
            }else{
                System.out.println("the annotation that we get is null");
            }
        }else{
            System.out.println("This is not the class that with FieldAnnotation");
        }
    }

    private static void testMethodAnnotation() throws Exception {
        Class<?> clazz = person.getClass();
        //因为是注解到method上的,所以首先要获取这个方法
        Method method = clazz.getDeclaredMethod("sayHello");
        if(method.isAnnotationPresent(MethodAnnotation.class)) {
            System.out.println("===This is a method with a annotation:MethodAnnotation===");
            //通过getAnnotation可以获取注解对象
            MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class);
            if(null != annotation) {
                System.out.println("MethodName = " + annotation.name());
                System.out.println("MethodType = " + annotation.type());
            }else{
                System.out.println("the annotation that we get is null");
            }
        }else{
            System.out.println("This is not the class that with MethodAnnotation");
        }
    }
}

3、执行截图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值