java 注解使用与注意事项

想拥有一个star过千的项目好难啊,费劲巴力的整出来star几天才有一个[捂脸],不过咱也不气馁,毕竟开发个东西出来对自己的技术也是个帮助不是。

wandfix开发了有一段时间了,在开发和使用的过程中也发现了一些问题,特别是帮助了我学习对于java 注解的使用。今天就打算分享我在这个项目中对于注解使用。

java注解在部分情况下是个可以帮助我们提升开发效率的东西,比如大名鼎鼎的控件绑定库 ButterKnife 当下比较热门的网络请求库retrofit ,在使用它们的过程中我们可以使用注解来非常方便的实现一些事情,比如最经典的findviewbyid。

我认为使用注解,一定要注意的有3点:

  1. 注解的元素
  2. 指定注解的使用范围,绑定在方法上还是class上等
  3. 指定注解的保留环境

定义一个注解

跟定义一个 class 差不多,class 关键字改成 @interface 就成了

public @interface BindProxy {
}

设置注解的元素

注解的参数仅支持以下数据类型:

  • Class
  • String
  • java八种基本类型
  • enum
  • Annotation
  • 上面类型的数组

注解的元素对默认值还有限制,元素不能有不确定的值。也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值,对于非基本类型的元素,无论是在源代码中声明,还是在注解接口中定义默认值,都不能以null作为值,元素使用 default 关键字设置默认值,例如:

public @interface BindProxy {
    ParentalEntrustmentLevel level()
            default ParentalEntrustmentLevel.NEVER;
}

指定注解的使用范围,绑定在方法上还是class上等

使用 @Target 指定注解的使用范围:

取值(ElementType)有:

  1. CONSTRUCTOR:用于描述构造器
  2. FIELD:用于描述域
  3. LOCAL_VARIABLE:用于描述局部变量
  4. METHOD:用于描述方法
  5. PACKAGE:用于描述包
  6. PARAMETER:用于描述参数
  7. TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Target({ElementType.TYPE})
public @interface BindProxy {
    //class name
    Class clazz();

    //双亲委托禁用级别
    ParentalEntrustmentLevel level()
            default ParentalEntrustmentLevel.NEVER;
}

指定注解的保留环境

指定注解的保留环境使用@Retention 元注解,这个务必要添加,因为如果不添加,注解当代码编译运行后可能被丢弃而失效。
取值(RetentionPoicy)有:

  1. SOURCE:在源文件中有效(即源文件保留)
  2. CLASS:在class文件中有效(即class保留)
  3. RUNTIME:在运行时有效(即运行时保留)
@Retention(RUNTIME)
@Target({ElementType.TYPE})
public @interface BindProxy {
    //class name
    Class clazz();

    //双亲委托禁用级别
    ParentalEntrustmentLevel level()
            default ParentalEntrustmentLevel.NEVER;
}

注解的使用

以上的@BindProxy注解是用来实现绑定activity代理的,activity代理就是实现一个类,代理activity生命周期的所有事物,而activity的生命周期中仅仅是将这个事件交给代理去处理。

被代理的 activity 代码

//绑定代理类
@BindProxy(clazz = TextActivityProxy.class)
//必须继承 ProxyActivity
public class TextActivity extends ProxyActivity {
    //这里什么都不用写
}

我在ProxyActivity 中进行了绑定:

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BindProxy proxyInfo = this.getClass().getAnnotation(BindProxy.class);
        //如果这个类没添加这个注解,证明这个activity不需要代理,直接返回
        if (proxyInfo == null) {
            return;
        }
        String proxyName = this.getClass().getAnnotation(BindProxy.class).clazz().getName();
        ParentalEntrustmentLevel level = this.getClass().getAnnotation(BindProxy.class).level();
        if (proxyName != null && proxyName.length() != 0) {
            proxy = ObjectFactory.make(proxyName, level, this);
            if (proxy != null) {
                proxy.onCreate(savedInstanceState);
            }
        }
    }

BindProxy proxyInfo = this.getClass().getAnnotation(BindProxy.class);这一句是拿到了注解中的值,然后通过反射进行了绑定。

这只是一个小小的例子,关于 @注解 还有更多的地方等你发掘。

发布了46 篇原创文章 · 获赞 62 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/qq_27512671/article/details/89332286