【Java】Java注解简单熟悉和了解

学而不思则罔,思而不学则殆


引言

最近在学习Retrofit网络请求框架,发现该框架中主要使用注解来封装内部逻辑,使开发的时候调用简洁。因此写一篇文章记录一下注解的相关知识

注解定义

Java 注解是在 JDK5 时引入的新特性,注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。注解类型定义指定了一种新的类型,一种特殊的接口类型。 在关键词 interface 前加 @ 符号也就是用 @interface 来区分注解的定义和普通的接口声明。目前大部分框架(如 Spring Boot 等)都通过使用注解简化了代码并提高的编码效率。

以上注解定义是复制的

注解分类

注解主要分为两类,元注解和普通注解

注解类别说明举例
元注解修饰注解的注解@Documented,@Target,@Retention
普通注解普通注解@Override

元注解

Target

该注解是标识注解使用的范围,取值是ElementType[]类型的数组

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

ElementType详解

ElementType原文说明
TYPEClass, interface (including annotation type), or enum declaration修饰类,接口或者枚举
FIELDField declaration (includes enum constants)修饰属性字段
METHODMethod declaration修饰方法
PARAMETERFormal parameter declaration修饰参数
CONSTRUCTORConstructor declaration修饰构造函数
LOCAL_VARIABLELocal variable declaration局部变量声明
ANNOTATION_TYPEAnnotation type declaration注解类型的说明
PACKAGEPackage declaration
TYPE_PARAMETERType parameter declaration-
TYPE_USEUse of a type-

Retention

该注解是描述注解的生命周期

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}
RetentionPolicy说明应用
SOURCE源码阶段存在,编译的时候丢弃用作提示
CLASS存在与字节码中,不会运行到JVM中在编译阶段根据注解生成java代码,比如ButterKnife
RUNTIME运行时存在反射相关的应用,比如Retrofit,效率低

普通注解

普通注解就没有啥好说的了,可以随便编写

@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Body {}
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
  /**
   * A relative or absolute path, or full URL of the endpoint. This value is optional if the first
   * parameter of the method is annotated with {@link Url @Url}.
   *
   * <p>See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
   * this is resolved against a base URL to create the full endpoint URL.
   */
  String value() default "";
}
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface POST {
  /**
   * A relative or absolute path, or full URL of the endpoint. This value is optional if the first
   * parameter of the method is annotated with {@link Url @Url}.
   *
   * <p>See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
   * this is resolved against a base URL to create the full endpoint URL.
   */
  String value() default "";
}

Method之获取注解

在Retrofit方法中有一段代码:

    //RequestFactory.java
    Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      this.methodAnnotations = method.getAnnotations();
      this.parameterTypes = method.getGenericParameterTypes();
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

根据method获取注解的相关参数,特验证熟悉一下
提供方法:

    interface BlogService {
        @Multipart
        @POST("register")
        Call<Blog> registerUser(@PartMap Map<String, RequestBody> params, @Part("password") RequestBody password);
    }

Method返回类型

            Method method = blogServiceClass.getDeclaredMethod("registerUser", Map.class, RequestBody.class);

            Class<?> returnType = method.getReturnType();
            Type genericReturnType = method.getGenericReturnType();
            System.out.println("returnType:" + returnType);
            System.out.println("genericReturnType:" + genericReturnType);

getReturnType返回普通的类型,getGenericReturnType则会返回更加细节,带上了泛型的类型

returnType:interface retrofit2.Call
genericReturnType:retrofit2.Call<com.example.test.AnnotatedTest$Blog>

Method的注解

            Annotation[] annotations = method.getAnnotations();
            Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
            System.out.println(Arrays.toString(annotations));
            System.out.println(Arrays.toString(declaredAnnotations));

可以看到,这里返回了registerUser方法的两个注解,Multipart和POST

[@retrofit2.http.Multipart(), @retrofit2.http.POST(value=register)]
[@retrofit2.http.Multipart(), @retrofit2.http.POST(value=register)]

Method的参数

            Class<?>[] parameterTypes = method.getParameterTypes();
            Type[] genericParameterTypes = method.getGenericParameterTypes();
            System.out.println(Arrays.toString(parameterTypes));
            System.out.println(Arrays.toString(genericParameterTypes));

同样返回了参数类型列表,差别不同的是,getGenericParameterTypes返回更加细化,携带了泛型类型

[interface java.util.Map, class okhttp3.RequestBody]
[java.util.Map<java.lang.String, okhttp3.RequestBody>, class okhttp3.RequestBody]

Method参数的注解

            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            System.out.println(Arrays.deepToString(parameterAnnotations));

这里返回注解的二维数组,因为每个参数可以有多个注解。

[[@retrofit2.http.PartMap(encoding=binary)], [@retrofit2.http.Part(encoding=binary, value=password)]]

注解的相关知识暂时就这些,待后续补充,学习中

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值