不管你爱与不爱,我写的对与错,我还是要接续写,写博客只是为了再加深了解,这里感谢老铁@duanjunxiao 的耐心指导,废话不多说了,继续加深一遍对注解的理解吧。
学习注解之前,我们首先要了解一个概念 “元注解”,元注解直白一点讲就是注解自定义的注解。本篇分为三个点来讲 1.元注解,2.自定义注解,3注解使用
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CardMap {
Class value();
}
上面@interface CardMap 是自定义注解,上面的@Retention、@Target是元注解,元注解还有@Inherited、@Documented,下面讲一下各个元注解。
元注解
1.@Target 修饰了Annotation的对象范围(Indicates the contexts in which an annotation type is applicable.)
取值(ElementType):
1. ElementType.TYPE 修饰Class、interface、enum
2.ElementType.FIELD 修饰 field 包括 enum
3.ElementType.METHOD 修饰 method 方法
4.ElementType.PARAMETER 修饰 parameter 参数
5.ElementType.CONSTRUCTOR 修饰 constructor 构造器
6.ElementType.LOCAL_VARIABLE 修饰 local_variable 局部变量
7.ElementType.ANNOTATION_TYPE 修饰 注解类型
8.ElementType.PACKAGE 修饰包
9.ElementType.TYPE_PARAMETER 修饰 参数类型(since 1.8)
10.ElementType.TYPE_USE 修饰 使用类型(since 1.8)
2.@Retention 修饰Annotation 注释被保留多长时间( Indicates how long annotations with the annotated type are to be retained.)
取值(RetentionPolicy):
1.RetentionPolicy.SOURCE 源文件中有效
2.RetentionPolicy.CLASS class文件中有效
3.RetentionPolicy.RUNTIME 运行时有效
3.@Documented
表明要记录的javadoc注释的类型和类似工具默认情况下。这种类型应该用于注释声明的类型注解影响客户使用带注释的元素。如果一个类型声明注释记录,其注释成为公共API的一部分带注释的元素。
4@Inherited
表明一个注释类型自动继承。如果存在一种遗传元注释的注释类型声明,和用户查询类声明的注释类型,和这种类型的类声明没有注释,那么类的超类将自动查询注释类型。这个过程会重复,直到找到这种类型的注释,或类层次结构的顶部(对象)。如果没有超类注释类型,则查询将表明,该类问题没有这样的注释。
直白一点讲就是被Inherited注释过的子类,在反射代码检查时,会检查class和父类。
自定义注解
自定义注解格式:public @interface 注解名 {注解体}
注解参数:1.基本数据类型 2.String 3.Class 4.enum 5.Annotation 6 数组
备注:如果注解体中只有一个成员时,最好将参数成员名称设为value()。上面例子中所示。
成员后面可以加 default+默认值。
自定义注解中必须要有值。
使用注解
我们所讲的例子是看了MultiType和老铁的demo以后,又想到了一个使用方法(老铁的项目中也是使用的注解,大概意思是使用注解在编译时生成了一个类,运行时,在adapter中将cardlist和providerlist通过生成的那个类赋值(将项目中所有注释类和对应的Model都放到cardlsit和providerlist中)),代码如下:
public class CardMapInitializer implements ICardMapInitializer {
@Override
public void initCardMap(List<String> cardNameList, List<String> providerNameList) {
cardNameList.add("com.entertainment.project.TestActivity");
providerNameList.add("com.entertainment.project.base.BaseBean");
cardNameList.add("com.entertainment.project.TestActivity");
providerNameList.add("com.entertainment.project.modules.humor.domain.HumorModel");
}
}
在adapter中写一个静态块调用这个类。
现在讲解我的一种方法,
/**
* Created by Sick on 2017/3/24.
*
* 收集实体类中的注解 @CardMap
*
*/
public class CardMapRouter {
private static HashMap<Class, String> cardMapHashMaps = new HashMap<>();
public static String getProviderName(Class<?> clazz) {
String providerName = cardMapHashMaps.get(clazz);
if (providerName == null) {
CardMap cardMap = clazz.getAnnotation(CardMap.class);
if (cardMap == null) {
throw new RuntimeException(String.format("%s must be is a annotation!", clazz.getSimpleName()));
}
providerName = cardMap.value().getName();
cardMapHashMaps.put(clazz, providerName);
}
return providerName;
}
}
HashMap中存储Class和ProviderNam e,注解在实体类上使用,如下
/** * Created by Sick on 2017/3/24.
*/ @CardMap(HumorProvider.class) public class HumorEntity extends BaseCard { public String b = "b"; public HumorEntity() { type = BaseCard.TYPE_CONTENT_2; } }
具体大家可以先去参考alibaba drakeet:https://github.com/drakeet/MultiType ,然后再返回来看此文章。