概述
使用枚举Enum能确保类型安全,但往往会加大内存消耗,因为Enum中的枚举值是静态成员对象,相对于静态常量占用更多的内存空间。google官方在很早以前就提醒尽量少的使用枚举,并提供了注解的方式来检查类型安全,目前提供了@IntDef
和@StringDef
这两种注解方式。
注解
一、@IntDef
定义注解,添加常量
@IntDef(value = {AnnotationStatus.TYPE_ONE, AnnotationStatus.TYPE_TWO})
@Retention(RetentionPolicy.SOURCE)
public @interface AnnotationStatus {
int TYPE_ONE = 0;
int TYPE_TWO = 1;
}
和接口一样,注解中的常量的类型也是public static final
修饰的。
@Retention
注解有三种类型,SOURCE
、CLASS
和RUNTIME
- SOURCE表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中。
- CLASS表示注解的信息被保留在class文件(字节码文件)中,当程序编译时,但不会被虚拟机读取在运行的时候。
- RUNTIME表示注解的信息被保留在class文件(字节码文件)中,当程序编译时,会被虚拟机保留在运行时。
@IntDef
用于限定可使用的int值
使用
@AnnotationStatus
private var property: Int = AnnotationStatus.TYPE_ONE
private fun setProperty(@AnnotationStatus prop: Int) {
this.property = prop
}
setProperty方法参数使用@AnnotationStatus
进行了注解,如果传入一个非@IntDef中定义的成员,则编译器lint检查会给予警告。
Must be one of: AnnotationStatus.TYPE_ONE, AnnotationStatus.TYPE_TWO
二、@StringDef
与@IntDef
的定义和使用类似,以下是完整代码:
@StringDef({AnnotationStrStatus.SUCCESS, AnnotationStrStatus.ERROR, AnnotationStrStatus.UNKNOWN})
@Retention(RetentionPolicy.SOURCE)
public @interface AnnotationStrStatus {
String SUCCESS = "success";
String ERROR = "error";
String UNKNOWN = "unknown";
}
@AnnotationStrStatus
private var requestStatus = AnnotationStrStatus.SUCCESS
private fun setRequestStatus(@AnnotationStrStatus reqStatus:String){
this.requestStatus = reqStatus
}
在属性上定义非注解限定之外的值,编译器报错提示:
注意:
一、kotlin定义的注解不起作用,查到以下资料,所以以上使用的定义的注解我都是用java写的
As of Kotlin 1.0.3, the @IntDef annotation is not supported, but support is planned for later versions.
The Kotlin way of making these compile time checks is to use an enum class instead of a series of Int constants.
二、对属性初始赋值可以进行限定,但二次赋值限定会失效(又或许是我哪没处理好==),目前处理是使用方法来进行属性赋值限定类型
三、对于有多个对应关系的还是需要使用枚举处理,注解方式处理不了,如Color(color_red,0,0xffffff)
四、@IntDef
和@StringDef
注解只是类型安全检查,在报错提示下强行运行,程序并不会发生发生闪退,实质上这两个注解就是用来约束规范的。