我正在尝试在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;
但正如您所看到的,我为其创建了两个不同的名称:SortTypeDef
和SortType
第三种方法:我尝试在@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
内?上述三种方法之间是否有任何性能差异?
答案 0 :(得分:10)
简短回答:对于简单项目,没关系,但对于更复杂的项目,首选方法是首选。
答案很长:
虽然sortType
的字节码在所有三种情况下都是相同的,但是存在差异。关键在于Retention
注释,它将保留策略设置为SOURCE
。这意味着您的SortType
注释是" to be discarded by the compiler",因此不会生成注释本身的字节码。
第一种方法定义注释之外的常规静态字段,并为它们生成常规字节码。第二种和第三种情况在注释中定义常量,并且不生成常量的字节码。
如果编译器可以访问包含SortType
声明的源文件,则任何一种方法都可以,sortType
的字节码是相同的。但是,如果无法访问源代码(例如,您只编译了库),则无法访问注释。对于第一种方法,只有注释本身不可访问,但对于后者,常量值也不可访问。
我曾经更喜欢第三种方法,因为它是最干净和最有条理的。我曾经有一天遇到过一个问题:当我开始为该代码编写Espresso测试时,编译器无法访问定义注释的源代码。我不得不切换到规范IntDef
声明或使用整数值而不是符号常量进行测试。
所以底线是:
答案 1 :(得分:3)
要使第三种方法有效,您应该在界面中命名values
。
我使用了你的代码并使其有效:
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;
选择一个,两者都应该有用。
答案 2 :(得分:1)
我来到这里希望找到为什么Android文档显示你的第一个方法,但第三种方法在生产代码中已经好几个月了。我没有看到任何理由不这样做。正如您所说,当您可能有多组相关常量时,它会清理命名空间。
答案 3 :(得分:-1)
似乎是一个很棒的地方...
public enum SortEnum {
DURATION,
PRICE,
TIME;
}