Android – 在@interface里放@IntDef值可以吗?

我试图在Android开发中实现@IntDef注释

第一种方法 :在Constant.java类中分隔的定义看起来很棒:

 public class Constant { @IntDef(value={SORT_PRICE, SORT_TIME, SORT_DURATION}) @Retention(RetentionPolicy.SOURCE) public @interface SortType{} public static final int SORT_PRICE = 0; public static final int SORT_TIME = 1; public static final int SORT_DURATION = 2; } 

用法:

 @Constant.SortType int sortType = Constant.SORT_PRICE; 

但是,当一个文件中有多个定义(例如UserType,StoreType等)时,事情会变得更加复杂。

第二种方法:所以我想出了这样的东西来分离定义之间的值:

 public class Constant { @IntDef(value={SortType.SORT_PRICE, SortType.SORT_TIME, SortType.SORT_DURATION}) @Retention(RetentionPolicy.SOURCE) public @interface SortTypeDef{} public static class SortType{ public static final int PRICE = 0; public static final int TIME = 1; public static final int DURATION = 2; } } 

用法:

 @Constant.SortTypeDef int sortType = Constant.SortType.PRICE; 

但是正如你所看到的,我为它创build了两个不同的名字: SortTypeDefSortType

第三种方法:我尝试在@interface内移动可能值的列表:

 public class Constant { @IntDef(value={SortType.SORT_PRICE, SortType.SORT_TIME, SortType.SORT_DURATION}) @Retention(RetentionPolicy.SOURCE) public @interface SortType{ int PRICE = 0; int TIME = 1; int DURATION = 2; } } 

用法

 @Constant.SortType int sortType = Constant.SortType.PRICE; 

虽然它确实有效,但我不知道是什么缺点。 @IntDef的可能值放在@interface里面@interface吗? 上述三种方法是否有性能差异?

为了使你的第三个方法工作,你应该像在界面中的名字一样。 我用你的代码,并使其工作:

 public class Constant { @IntDef(value = {SortType.PRICE, SortType.TIME, SortType.DURATION}) @Retention(RetentionPolicy.SOURCE) @interface SortType { int PRICE = 0; int TIME = 1; int DURATION = 2; } } 

要么

 public class Constant { @IntDef(value = {SortType.SORT_PRICE, SortType.SORT_TIME, SortType.SORT_DURATION}) @Retention(RetentionPolicy.SOURCE) @interface SortType { int SORT_PRICE = 0; int SORT_TIME = 1; int SORT_DURATION = 2; } } 

第二用法:

 @Constant.SortType int sortType = Constant.SortType.SORT_DURATION; 

挑一个,都应该工作。

我来这里希望能find为什么Android文档显示你的第一个方法,但第三个方法已经在我的生产代码工作好几个月。 我没有看到有任何理由不这样做。 正如你所说的,当你可能有多组相关的常量时,它会清理命名空间。

简单的答案 :对于简单的项目,这是可以的,但对于更复杂的第一种方法是首选。

长答案 :尽pipesortType字节码在所有三种情况下都是相同的,但是还是有区别的。 关键在于Retention注释,它将保留策略设置为SOURCE 。 这意味着你的SortType注解是“ 被编译器丢弃 ”的,所以不会生成注释本身的字节码。

第一种方法是在注释之外定义常规的静态字段,并为其生成常规的字节码。 第二和第三种情况在注释中定义常量,并且不会生成常量的字节码。

如果编译器可以访问包含SortType声明的源文件,那么任何一种方法都可以, sortType字节码是相同的。 但是,如果源代码不可访问(例如,你只有编译库),注释是不可访问的。 对于第一种方法,只有注解本身是不可访问的,但是对于后者,常量值不能被访问。

我曾经更喜欢第三种方法,因为它是最干净和结构化的。 直到有一天,我遇到了一个问题:当我开始为代码编写Espressotesting时,编译器无法访问定义注释的源代码。 我不得不切换到规范的IntDef声明,或者使用整数值而不是符号常量来进行testing。

所以底线是:

  • 坚持规范的方式,除非你的注释是在你的代码的内部,你不从别处引用它,包括testing

看起来像是一个em good的好地方…

public enum SortEnum {DURATION,PRICE,TIME; }