在Android中使用枚举


120

我几乎要完成在Android中为我的应用程序进行的计算活动。我尝试创建一个性别枚举,但是由于某种原因出现语法错误,请插入“ EnumBody”以完成EnumDeclaration。

public static enum Gender
{
    static
    {
        Female = new Gender("Female", 1);
        Gender[] arrayOfGender = new Gender[2];
        arrayOfGender[0] = Male;
        arrayOfGender[1] = Female;
        ENUM$VALUES = arrayOfGender;
    }
}

我也尝试了不使用静态{}的情况,但是出现了相同的语法错误。


对于性能问题,不建议使用枚举,而应使用原始常量。youtube.com/watch?v=Hzs6OBcvNQE
Myke Dev

更新2019:枚举在Android中很好用,因为ART取代了DALVIK作为运行时环境stackoverflow.com/a/56296746/4213436。因此,我认为此线程上的大多数答案都无关紧要。
JDenais

@JDenais当然是指您刚刚引用的线程“ you”
YoussefDir

Answers:


343

您到底在哪里找到这种语法?Java枚举非常简单,您只需指定值即可。

public enum Gender {
   MALE,
   FEMALE
}

如果您希望它们更复杂,可以像这样向它们添加值。

public enum Gender {
    MALE("Male", 0),
    FEMALE("Female", 1);

    private String stringValue;
    private int intValue;
    private Gender(String toString, int value) {
        stringValue = toString;
        intValue = value;
    }

    @Override
    public String toString() {
        return stringValue;
    }
}

然后使用枚举,您将执行以下操作:

Gender me = Gender.MALE

11
我会尝试一下,我确实说过我是一个绝对的初学者
JMSDEV 2012年

86
抱歉,我不是那个意思。只是我见过一个枚举最奇怪的语法
Spidy

3
列举枚举是顺序的,这也很有帮助,因此您可以在枚举上使用.ordinal()来获取int值。
Kalel Wade 2014年

1
问题中的语法是使用反编译器可能产生的语法。
Dan Getz

9
我对“您在哪里找到了这种语法”大笑。话说就像一个老师对他的学生
扎尔ËAhmer

50

关于这一点争论不休,但是即使在最近的文档中,android也建议在android应用程序中使用枚举并不是一个好主意。原因是因为它们比静态常量变量占用更多的内存。这是2014年网页上的文档,建议您不要在Android应用程序中使用枚举。http://developer.android.com/training/articles/memory.html#Overhead

我引用:

注意内存开销

熟悉使用的语言和库的成本和开销,并在设计应用程序时始终牢记这些信息。通常,表面上看起来无害的东西实际上可能有大量的开销。示例包括:

  • 枚举通常需要比静态常量多两倍的内存。您应严格避免在Android上使用枚举。

  • Java中的每个类(包括匿名内部类)都使用大约500字节的代码。

  • 每个类实例都有12-16字节的RAM开销。

  • 将单个条目放入HashMap需要分配一个占用32个字节的附加条目对象(请参阅有关优化数据容器的上一节)。

随处可见的几个字节很快就累加了,类或对象繁重的应用程序设计将遭受这种开销。这会使您处于查看堆分析的困境,并且意识到问题是很多小对象占用了RAM。

他们在某些地方说这些技巧已经过时了,不再有价值,但是他们不断重复这些技巧的原因一定是其中有些道理。编写android应用程序是您应该尽可能轻巧的操作,以实现流畅的用户体验。每一点点的性能都至关重要!


已经有一些地方 -如果您知道的话,可以添加一些吗?因为我找不到任何东西
Krzysztof Skrzynecki 2015年

9
在这里,有人注意到有关使用int而不是枚举的信息已从官方文档中的Performance Tips中。此外,我做了研究,并张贴总结Reddit上
克日什托夫·Skrzynecki


伙计们,我的问题是,如果Enum是“不好的”做法,为什么Google在Android上仍支持Java的此功能?:(
赫苏斯·卡斯特罗

5
@JesúsCastro因为Google希望确保拥有大量现有Java业务逻辑(可能正在使用枚举)的公司可以将其库放入Android项目中就可以了。
大卫·布朗

22

正如Chris所评论的那样,枚举在Android上需要更多的内存,随着它们在任何地方都被使用,它们的总和会增加。您应该改用IntDefStringDef,它们使用批注,以便编译器验证传递的值。

public abstract class ActionBar {
...
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
@Retention(RetentionPolicy.SOURCE)
public @interface NavigationMode {}

public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;

@NavigationMode
public abstract int getNavigationMode();

public abstract void setNavigationMode(@NavigationMode int mode);

它也可以用作标志,允许二进制组合(OR / AND操作)。

编辑:似乎将枚举转换为整数是Proguard中的默认优化之一


3
我喜欢将int常量直接放入注释类中。因此,它看起来像常规枚举。我在这里描述过:blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.


9

根据此视频,如果您使用ProGuard,您甚至都不需要考虑Enums性能问题!!

在许多情况下,Proguard可以代表您优化Enums到INT值,因此实际上无需考虑或做任何工作。


4

Android的首选方法是使用@IntDef强制执行的int常量:

public static final int GENDER_MALE = 1;
public static final int GENDER_FEMALE = 2;

@Retention(RetentionPolicy.SOURCE)
@IntDef ({GENDER_MALE, GENDER_FEMALE})
public @interface Gender{}

// Example usage...
void exampleFunc(@Gender int gender) {
  switch(gender) {
  case GENDER_MALE:

     break;
  case GENDER_FEMALE:
     // TODO
     break;
  }
}

文件:https//developer.android.com/studio/write/annotations.html#enum-annotations

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.