Java注解详解

  • 什么是注解?

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 比如我们常见的@Override和@Deprecated都是注解,注解可以加在类、方法、成员变量等上面,类似于给他们“打标签"。

  • 注解怎么定义?

public @interface 注解名{} 看起来和定义接口很相似只是多了一个@符号 接口: public interface 接口名 注解: public @interface 注解名

public @interface myapt{
    
}
  • 注解怎么使用?

现在我们注解已经定义好了,使用的时候直接“@注解名”就可以使用了 比如下面我们可以定义在“类、成员变量、成员方法”上:

现在注解定义好也已经使用了,但是我不想定义到类上和成员方法上,只想定义在成员方法上,如何才能让注解只能定义到方法上,定义到别的地方报错呢? 想要的效果:

这个时候就要使用元注解来限定范围了。

  • 元注解

元注解通俗的来说就是定义在注解上的注解,在Java中有四个元注解 @Target @Retention @Documented @Inherited

  • @Target

@Target就是用于描述注解的定义范围,可以限制这个注解定义的元素类型。

参数作用
ElementType.ANNOTATION_TYPE可以应用于注解类型
ElementType.CONSTRUCTOR可以应用于构造函数
ElementType.FIELD可以应用于字段或属性
ElementType.LOCAL_VARIABLE可以应用于局部变量
ElementType.METHOD可以应用于方法级注解
ElementType.PACKAGE可以应用于包声明
ElementType.PARAMETER可以应用于方法的参数
ElementType.TYPE可以应用于类的任何元素

要限制只想定义在成员变量上,所以我们应该使用ElementType.FIELD

@Target({ElementType.FIELD,ElementType.METHOD})
public @interface myapt {

}
  • @Retention

@Retention是用于定义注解的生命周期,也可以理解为存储方式。

参数作用
RetentionPolicy.SOURCE标记的注解仅保留在源级别中,并被编译器忽略
RetentionPolicy.CLASS标记的注解在编译时由编译器保留,但 Java 虚拟机(JVM)会忽略
RetentionPolicy.RUNTIME标记的注解由 JVM 保留,因此运行时环境可以使用它

下面两个元注解使用不多,暂时不做详解

  • @Documented

@Documented是用于描述生成帮助文档时是否要保留其注解信息。

  • @Inherited

@Inherited是用于描述使被它修饰的注解是否具有继承性。

  • 注解元素

上面我们只是定义了一个注解,但是不能传任何信息,只是相当于一个标签,现在我们看看要怎么给注解定义参数:

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface lkx {
    String name() default "张三"; //可以使用default定义默认的值
    int age();
}

  • 注意事项:

  1. 下面代码需要用到反射,如果还不会的小伙伴可以看我前面几篇文章。
  2. 因为要用反射拿到注解参数,所以@Retention需要定义为RetentionPolicy.RUNTIME

实现代码:

public class APTTest {


    @Target({ElementType.FIELD,ElementType.METHOD}) -----//定义注解只能给谁使用
    @Retention(RetentionPolicy.RUNTIME)
    public @interface myapt{

         String b() default "dvalue";  ----- //默认dvalue
         int a();
    }

 
    @myapt(age = 18)  ---------  //可以用来传参
    private static int bl1;

    @myapt(name = "test2",age = 38)
    private static String bl2;

    public static void main(String[] args) throws Exception {


        APTTest tt = new APTTest();
        System.out.println("赋值前: bl1: " + bl1+"   bl2: "+bl2);

        //拿到类的字节码
        Class<Test> testClass = APTTest.class;
        //拿到所有成员变量
        for (Field declaredField : testClass.getDeclaredFields()) {
            //检测成员变量上是否有 "我们定义“”的注解
            if (declaredField.isAnnotationPresent(lkx.class)) {

                myapt annotation = declaredField.getAnnotation(lkx.class);
                //获取到注解中的的值
                int tmpa = annotation.a();
                String tmpb = annotation.b();

     System.out.println("通过for循环拿到类里面的变量 a+ " + tmpa + ", b:"+ b );

                //declaredField.set(testClass.newInstance(),age);
                //declaredField.set(tt,age);
            }
        }

   
    }
}

@BindView(R.id.groupChat)
Button mGroupChat;

@BindView(R.id.privateChat)
Button mPrivateChat;

注意:  因为注解是使用反射机制的, 所以会影响 “性能

启动性能、执行性能

可以看一下

butterknife框架

viewbing的源码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值