Enums and android annotation intDef
Asked Answered
Y

4

47

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.

Ytterbium answered 16/8, 2015 at 6:34 Comment(3)
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.Ecotone
@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.Avan
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.Derivation
G
65

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.

Groupie answered 7/2, 2016 at 9:18 Comment(3)
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.Ytterbium
Well then intdef is not for you. The point of intdef is to remove enum's overhead.Haematin
Any idea how to use it with kotlin?Hegyera
E
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

Ecotone answered 16/8, 2015 at 7:14 Comment(5)
i don't want to handle values of AppEnum parameters manually, Enum create values automatically ordinarily.Ytterbium
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 annotationEcotone
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 declarationsEustazio
"You should strictly avoid using enums on Android" -- few Java and Android experts agree with the presenter on that video. See Jake Wharton, Bob Lee, and Joshua Bloch, for example.Cosine
@Eustazio 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.Derivation
P
1
@Retention(RetentionPolicy.SOURCE)
@IntDef({NOT_STARTED, PENDING, COMPLETED})
public @interface DownloadState {
    int NOT_STARTED = 1;
    int PENDING = 2;
    int COMPLETED = 3;
}
Pontiff answered 23/5, 2018 at 6:45 Comment(1)
This is basically used for best way to use IntDef in place of Enum.This code is working fine for me. Please try itPontiff
L
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

Liturgics answered 30/9, 2019 at 13:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.