46

I have an enum:

public enum AppEnums {
    SERVICE_ERROR,
    CONNECTION_ERROR;
}

and I want to use it in an intDef of Android Annotation:

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

error shows:

incompatible types found, required: 'long'

What I can do with this incompatibility?

I don't want to handle values of AppEnum parameters manually, Enum create values automatically ordinarily. AppEnums.CONNECTION_ERROR.ordinal() return int value of enum parameter but don't work here.

AliSh
  • 10,085
  • 5
  • 44
  • 76
  • 1
    Well, you can't quite do it that way. AppEnums .SERVICE_ERROR will never return int; it will return AppEnums .SERVICE_ERROR. That's the point of enumerated types. – Bhargav Aug 16 '15 at 07:09
  • 4
    `@IntDef` works only with integer. If you want to work with an Enum you don't need the `@IntDef`. Just use the Enum as a parameter. – Gabriele Mariotti Sep 05 '15 at 18:55
  • You should never rely on the ordinal value of enum constants, since changing the order of the constants would subtly break your code -- the worst kind of breakage. – Kevin Krumwiede Feb 14 '16 at 07:03

4 Answers4

64

The main idea of IntDef annotation is to use set of int constants like an enum, but without enum. In this case you have to declare all constants manually.

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

You can see detailed example here.

Oleksii K.
  • 5,359
  • 6
  • 44
  • 72
  • i don't want to handle values of AppEnum parameters manually, Enum create values automatically ordinarily. AppEnums.CONNECTION_ERROR.ordinal() return int value of enum parameter but don't work here. – AliSh Feb 14 '16 at 06:45
  • 3
    Well then intdef is not for you. The point of intdef is to remove enum's overhead. – Teovald May 19 '17 at 15:33
11

Well, you can't quite do it that way. AppEnums.SERVICE_ERROR will never return int; it will return AppEnums.SERVICE_ERROR. That's the point of enumerated types.

What I can suggest is this:

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

Copied from Yazazzello's comment below:

IntDef - new Enums for Android development. Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android. so IntDef where designed to replace Enums, you cannot use Enum in IntDef declarations

Bhargav
  • 8,118
  • 6
  • 40
  • 63
  • i don't want to handle values of AppEnum parameters manually, Enum create values automatically ordinarily. – AliSh Aug 16 '15 at 07:29
  • 1
    yes they do but they are not considered constant values, you could use the ordinal() method for Enums and assign it to some constant fields and use those constant fields in the IntDef annotation – Bhargav Aug 16 '15 at 07:36
  • 4
    IntDef - new Enums for Android development. [Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.](https://developer.android.com/training/articles/memory.html#Overhead) so IntDef where designed to replace Enums, you cannot use Enum in IntDef declarations – Yazazzello Sep 07 '15 at 08:41
  • 14
    "You should strictly avoid using enums on Android" -- few Java and Android experts agree with the presenter on that video. See [Jake Wharton](https://twitter.com/JakeWharton/status/638447874515275776), [Bob Lee](https://twitter.com/crazybob/status/636959556539539457), and [Joshua Bloch](https://twitter.com/joshbloch/status/628663950389841920), for example. – CommonsWare Sep 07 '15 at 13:55
  • 4
    @Yazazzello The standard Android "Hello, world" involves thousands of classes and tens of thousands of objects. I guarantee that using enums will have no perceptible effect on performance. If your app would benefit from the increased type safety of an enum, always use an enum. – Kevin Krumwiede Feb 14 '16 at 07:01
1
@Retention(RetentionPolicy.SOURCE)
@IntDef({NOT_STARTED, PENDING, COMPLETED})
public @interface DownloadState {
    int NOT_STARTED = 1;
    int PENDING = 2;
    int COMPLETED = 3;
}
Alok Singh
  • 640
  • 4
  • 14
  • This is basically used for best way to use IntDef in place of Enum.This code is working fine for me. Please try it – Alok Singh May 23 '18 at 06:47
0

the annotated element of integer type, represents a logical type and that its value should be one of the explicitly named constants.

NOTE: If the IntDef#flag() attribute is set to true, multiple constants can be combined.

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

  int CONNECTION_ERROR = 0;
  int SERVICE_ERROR = 1;
}

NOTE: If the IntDef#flag() attribute is set to true, multiple constants can be combined.

also you can Using @LongDef for long values and @StringDef for StringValues

Aslami.dev
  • 880
  • 8
  • 19