枚举和Android注释IntDef

47

我有一个枚举:

public enum AppEnums {
    SERVICE_ERROR,
    CONNECTION_ERROR;
}

我想在Android Annotation的intDef中使用它:

@IntDef({AppEnums.CONNECTION_ERROR, AppEnums.SERVICE_ERROR})
public @interface ServiceErrors {
}

错误显示:

找到不兼容的类型,需要:'long'

我该如何处理这种不兼容性?

我不想手动处理AppEnum参数的值,枚举通常会自动创建值。 AppEnums.CONNECTION_ERROR.ordinal() 返回枚举参数的整数值,但在这里不起作用。


1
嗯,你不能用那种方式来做。AppEnums.SERVICE_ERROR永远不会返回int;它将返回AppEnums.SERVICE_ERROR。这就是枚举类型的意义所在。 - Bhargav
4
@IntDef 只适用于整数。如果您想使用枚举类型,就不需要 @IntDef。只需将枚举作为参数即可。 - Gabriele Mariotti
你永远不应该依赖于枚举常量的序数值,因为改变常量的顺序会微妙地破坏你的代码——这是最糟糕的一种破坏。 - Kevin Krumwiede
4个回答

65

IntDef注解的主要思想是使用一组int常量,类似于enum,但不需要enum。 在这种情况下,您必须手动声明所有常量。

@IntDef({Status.IDLE, Status.PROCESSING, Status.DONE, Status.CANCELLED})
@Retention(RetentionPolicy.SOURCE)
@interface Status {
    int IDLE = 0;
    int PROCESSING = 1;
    int DONE = 2;
    int CANCELLED = 3;
}
你可以在这里看到详细的例子。

我不想手动处理AppEnum参数的值,通常情况下枚举会自动创建值。AppEnums.CONNECTION_ERROR.ordinal()返回枚举参数的int值,但在这里不起作用。 - AliSh
3
那么,如果你不想要,intdef不适合你。 intdef的目的是为了消除enum的开销。 - Teovald
有没有想法如何在Kotlin中使用它? - undefined

11

嗯,你不能完全这样做。 AppEnums.SERVICE_ERROR 永远不会返回 int;它将返回 AppEnums.SERVICE_ERROR。 这就是枚举类型的用途所在。

我可以建议的是:

public static class AppEnums {
    public static final int CONNECTION_ERROR = 0;
    public static final int SERVICE_ERROR = 1;
}

@IntDef({AppEnums.CONNECTION_ERROR,AppEnums.SERVICE_ERROR})
    public @interface ServiceErrors {
}

以下内容来自Yazazzello的评论:

IntDef是Android开发中的新枚举。 枚举常常需要比静态常量占用多两倍以上的内存。在Android上,您应该严格避免使用枚举。因此,IntDef被设计用来替代枚举,您不能在IntDef声明中使用Enum


我不想手动处理AppEnum参数的值,通常情况下枚举会自动创建值。 - AliSh
1
是的,但它们不被视为常量值,您可以使用Enums的ordinal()方法并将其分配给一些常量字段,并在IntDef注释中使用这些常量字段。 - Bhargav
4
IntDef是Android开发中用于替换Enums的新枚举类型。Enums通常需要比静态常量多两倍以上的内存,因此在Android开发中应严格避免使用它们。因此,IntDef被设计用来替代Enums,在IntDef声明中不能使用Enum。 - Yazazzello
14
“你应该严格避免在Android上使用枚举” - 一些Java和Android专家不同意视频演示者的说法。例如,请查看Jake Wharton、Bob Lee和Joshua Bloch的推文。 - CommonsWare
4
标准的Android "Hello, world"程序涉及数千个类和成千上万的对象。我保证使用枚举对性能没有明显影响。如果您的应用程序从枚举类型安全性的增加中受益,那么请始终使用枚举。 - Kevin Krumwiede

1
@Retention(RetentionPolicy.SOURCE)
@IntDef({NOT_STARTED, PENDING, COMPLETED})
public @interface DownloadState {
    int NOT_STARTED = 1;
    int PENDING = 2;
    int COMPLETED = 3;
}

这基本上是用于最佳方式使用IntDef代替Enum。这段代码对我来说运行良好。请尝试它。 - Alok Singh

0

整数类型的注释元素表示逻辑类型,其值应为明确命名的常量之一。

注意:如果IntDef#flag()属性设置为true,则可以组合多个常量。

@IntDef(flag = false,value = {AppEnums.CONNECTION_ERROR, AppEnums.SERVICE_ERROR})
@Retention(RetentionPolicy.SOURCE)
public @interface AppEnums {

  int CONNECTION_ERROR = 0;
  int SERVICE_ERROR = 1;
}

注意:如果IntDef#flag()属性设置为true,则可以组合多个常量。

您还可以使用@LongDef表示长整型值,使用@StringDef表示字符串值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接