本文介绍了Android官方推荐避免使用枚举的原因,并详细讲解了如何通过@IntDef注解创建内存更高效的解决方案。通过示例展示了如何在Java和Kotlin中使用该注解,并指出Kotlin中的使用情况。
Android官方不推荐使用枚举,因为使用枚举占用内存大,相比于静态常量Enum会花费两倍以上的内存。因此就有另一种方式来替代枚举类的使用,那就是@IntDef注解。
枚举的理解
首先谈谈对枚举的理解,虽说平时用枚举不是很多,在某些情况下还是会用到枚举的。
1、枚举是某个类的有限集合,它的对象个数不可由程序员增减,它的对象在一个枚举类生成的时候已经确定。
2、枚举可以避免程序调用者使用了系统规定之外的变量,造成未知错误。比如程序需要使用第三方SDK,传入了SDK未能处理的变量,造成SDK异常错误,如果使用了枚举,就可在编码时发现传入错误参数。
@IntDef注解的使用
添加依赖:
implementation 'com.android.support:support-annotations:26.1.0'
java 中使用@IntDef
使用示例:
//方式一
public class Test {
//先定义 常量
public static final int SUNDAY = 0;
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;
//用 @IntDef "包住" 常量;
// @Retention 定义策略
// 声明构造器
@IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY})
@Retention(RetentionPolicy.SOURCE)
public @interface WeekDays {}
@WeekDays private int currentDay = SUNDAY;
public void setCurrentDay(@WeekDays int currentDay) {
this.currentDay = currentDay;
}
@WeekDays
public int getCurrentDay() {
return currentDay;
}
}
//方式二
@IntDef({SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY})
@Retention(RetentionPolicy.SOURCE)
public @interface WeekDays {
int SUNDAY = 0;
int MONDAY = 1;
int TUESDAY = 2;
int WEDNESDAY = 3;
int THURSDAY = 4;
int FRIDAY = 5;
int SATURDAY = 6;
}
kotlin 中使用@IntDef
在kotlin中使用@IntDef注解,发现没有什么用,起不到限定作用,仍然可以随便传入值,测试代码如下:
@IntDef(
WeekDays.SUNDAY,
WeekDays.MONDAY,
WeekDays.TUESDAY,
WeekDays.WEDNESDAY,
WeekDays.THURSDAY,
WeekDays.FRIDAY,
WeekDays.SATURDAY
)
@Retention(RetentionPolicy.SOURCE)
annotation class WeekDays {
companion object {
const val SUNDAY = 0
const val MONDAY = 1
const val TUESDAY = 2
const val WEDNESDAY = 3
const val THURSDAY = 4
const val FRIDAY = 5
const val SATURDAY = 6
}
}
class Test1 {
private var currentDay = WeekDays.SUNDAY
@WeekDays
fun get():Int = currentDay
fun setCurrentDay(@WeekDays currentDay: Int){
this.currentDay = currentDay
}
}
fun main(arg:Array<String>){
var test1 = Test1()
test1.setCurrentDay(123)
println(test1.get())
}
@Retention
@Retention是一个Java注解,用于指定注解的生命周期。它有三个配置选项:RetentionPolicy.SOURCE、RetentionPolicy.CLASS和RetentionPolicy.RUNTIME。
1、RetentionPolicy.SOURCE:表示注解仅存在于源代码中,编译成字节码后会被丢弃。这意味着在运行时无法获取到该注解的信息,只能在编译时使用。通常用于一些编译器相关的注解,如@Override。
2、RetentionPolicy.CLASS:表示注解存在于源代码和字节码中,但在运行时会被丢弃。这意味着在编译时和字节码中可以通过反射获取到该注解的信息,但在实际运行时无法获取。通常用于一些框架和工具的注解,如Spring的@Autowired。
3、RetentionPolicy.RUNTIME:表示注解存在于源代码、字节码和运行时中。这意味着在编译时、字节码中和实际运行时都可以通过反射获取到该注解的信息。通常用于一些需要在运行时处理的注解,如JUnit的@Test。
@Target
@Target注解是用来指定注解应用的目标位置。在Kotlin中,您可以使用AnnotationTarget枚举来指定注解的目标位置。
// 注解可以应用于函数参数和字段上
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD)
annotation class MyAnnotation
// 该注解只能应用于函数上
@Target(AnnotationTarget.FUNCTION)
annotation class MyFunctionAnnotation
// 该注解只能应用于类或接口上
@Target(AnnotationTarget.CLASS)
annotation class MyClassAnnotation