Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android-可以将@IntDef值放在@interface中吗?_Java_Android_Annotations - Fatal编程技术网

Java Android-可以将@IntDef值放在@interface中吗?

Java Android-可以将@IntDef值放在@interface中吗?,java,android,annotations,Java,Android,Annotations,我试图在Android开发中实现@IntDef注释 第一个方法:将定义分隔在一个常量中看起来很棒。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;

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

第一个方法:将定义分隔在一个
常量中看起来很棒。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;
@Constant.SortTypeDef int sortType = Constant.SortType.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.SortType int sortType = Constant.SORT_PRICE;
@Constant.SortTypeDef int sortType = Constant.SortType.PRICE;
但正如您所看到的,我为它创建了两个不同的名称:
SortTypeDef
SortType

第三种方法:我试图在
@界面中移动可能值的列表

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
中吗?以上三种方法的性能有什么不同吗?

似乎是枚举的好地方

public enum SortEnum {
    DURATION,
    PRICE,
    TIME;
}

我来这里是想知道为什么Android文档会显示你的第一种方法,但是第三种方法在我的生产代码中已经运行了好几个月了。我看不出有什么理由不那样做。正如您所说,当您可能有多组相关常量时,它会清理名称空间。

要使第三个方法工作,您应该像在界面中一样命名
值。
我使用了您的代码并使其正常工作:

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;
    }
}

第二种用法:

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

选择一个,两者都应该有效。

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

长答案: 虽然
sortType
的字节码在所有三种情况下都是相同的,但存在差异。关键在于
Retention
注释,它将保留策略设置为
SOURCE
。这意味着您的
SortType
注释是“”,因此不会生成注释本身的字节码

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

如果编译器可以访问包含
SortType
声明的源文件,则两种方法都可以,并且
SortType
的字节码是相同的。但如果源代码不可访问(例如,您只有编译过的库),则无法访问注释。对于第一种方法,只有注释本身是不可访问的,但是对于后一种方法,常量值也是不可访问的

我过去更喜欢第三种方法,因为它最干净、最有条理。直到有一天我遇到了一个问题:当我开始为代码编写浓缩咖啡测试时,编译器无法访问定义注释的源代码。我必须切换到规范的
IntDef
声明,或者在测试中使用整数值而不是符号常量

因此,底线是:

  • 除非注释是代码内部的,并且您不从任何其他地方(包括测试)引用它,否则请坚持使用规范方法

您找到这个问题的解决方案了吗?我现在也在想同样的问题…@IgorGanapolsky还没有,但我继续在生产代码上使用第三种方法,到目前为止没有问题。我认为最好的检查方法是分析(用法、常量数等)。IntDef注释只有RetentionPolicy.SOURCE,因此仅由编译器注释处理器使用。它不可能对运行时性能产生影响,除非注释处理器正在做一些非常深奥的事情,例如使用字节码编织或代码生成将运行时检查插入到代码中。idk,自从我观看之后,我一直在避免使用enum。假设视频是2 y.o,并且很多事情可能已经发生了变化。Intdef是专门为资源受限系统中的枚举替换而设计的。建议用Enum替换它们既不能回答问题,也无助于对话。在Ahmad指出之前,他并不知道Android中的Enum问题。我一直在使用Java,但直到最近才使用Android,在我看来OP实现了一种反模式。但是,由于在Android上研究枚举的问题,我将避免使用它们,并检查IntDefs。@Nineplan失败如果使用proguard,您可以毫无问题地使用枚举,因为proguard将在编译发布时替换它们。