Android에서 열거 형 작업


120

내 앱을 위해 Android에서 작업중인 계산 활동이 거의 완료되었습니다. Gender Enum을 만들려고하는데 어떤 이유로 Syntax 오류가 발생하면 "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

UPDATE 2019 : ART가 런타임 환경 stackoverflow.com/a/56296746/4213436으로 DALVIK를 대체했기 때문에 Android에서 열거 형을 사용하는 것이 좋습니다 . 따라서이 스레드에 대한 대부분의 답변은 관련이 없다고 생각합니다.
JDenais

@JDenais 물론 방금 참조한 스레드 '당신'을 의미합니다
YoussefDir

답변:


343

도대체 어디에서이 구문을 찾았습니까? Java Enum은 매우 간단하며 값만 지정하면됩니다.

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

12
나는 시도는, 내가 절대 초보자이었다라고 않았다 줄 것이다
JMSDEV

87
죄송합니다. 부정적으로 말씀하신 것이 아닙니다. 내가 열거하기위한 본 적이 그냥 이상한 구문
Spidy

4
열거 형이 순차적이므로 열거 형에 .ordinal ()을 사용하여 int 값을 가져올 수 있다는 것도 언급하는 데 도움이됩니다.
Kalel Wade 2014

1
질문의 구문은 디 컴파일러를 사용하여 얻을 수있는 종류입니다.
Dan Getz

9
나는 "어디에서이 구문을 찾았습니까?"에 대해 많이 웃었습니다. 그의 학생에게 선생님처럼 말하는
자르 E Ahmer

50

이 논쟁 점에 대해 약간의 논쟁이 있었지만, 가장 최근의 문서에서도 android는 안드로이드 애플리케이션에서 열거 형을 사용하는 것이 좋지 않다고 제안합니다. 그 이유는 정적 상수 변수보다 더 많은 메모리를 사용하기 때문입니다. 다음은 Android 애플리케이션에서 열거 형 사용을 금지하는 2014 년 페이지의 문서입니다. http://developer.android.com/training/articles/memory.html#Overhead

나는 인용한다 :

메모리 오버 헤드에주의

사용중인 언어 및 라이브러리의 비용과 오버 헤드에 대해 잘 알고 있어야하며 앱을 처음부터 끝까지 디자인 할 때이 정보를 염두에 두십시오. 종종 표면에 무해 해 보이는 것들은 실제로 많은 양의 오버 헤드를 가질 수 있습니다. 예는 다음과 같습니다.

  • 열거 형은 종종 정적 상수보다 두 배 이상의 메모리를 필요로합니다. Android에서 열거 형 사용을 엄격히 피해야합니다.

  • Java의 모든 클래스 (익명 내부 클래스 포함)는 약 500 바이트의 코드를 사용합니다.

  • 모든 클래스 인스턴스에는 12-16 바이트의 RAM 오버 헤드가 있습니다.

  • HashMap에 단일 항목을 넣으려면 32 바이트를 사용하는 추가 항목 개체를 할당해야합니다 (최적화 된 데이터 컨테이너에 대한 이전 섹션 참조).

여기저기서 몇 바이트가 빠르게 추가됩니다. 클래스 또는 객체가 많은 앱 디자인은이 오버 헤드로 인해 어려움을 겪습니다. 그러면 힙 분석을 살펴보고 문제가 RAM을 사용하는 많은 작은 개체라는 것을 깨닫는 어려운 위치에 놓일 수 있습니다.

이 팁이 오래되어 더 이상 가치가 없다고 말하는 곳이 있지만 계속 반복하는 이유는 진실이 있음에 틀림 없습니다. 안드로이드 애플리케이션을 작성하는 것은 원활한 사용자 경험을 위해 가능한 한 가볍게 유지해야하는 것입니다. 그리고 모든 작은 성능이 중요합니다!


장소가 몇 군데 있습니다. 아는 경우 추가 할 수 있습니까? 나는 어떤 찾을 수 없기 때문에
르지 Skrzynecki

9
여기 누군가가 enum 대신 int를 사용하는 것에 대한 정보 가 공식 문서의 Performance Tips 에서 제거되었음을 알았습니다 . 또한, 나는 reddit
Krzysztof Skrzynecki


여러분, 제 질문은 Enum이 "나쁜"관행이라면 왜 Google은 Android에서이 Java 기능을 계속 지원합니까? :(
Jesús Castro

5
@ JesúsCastro Google은 기존 Java 비즈니스 로직 (열거 형을 사용하고있을 수 있음)이 많은 회사가 라이브러리를 Android 프로젝트에 넣고 이동할 수 있도록하기를 원하기 때문입니다.
David Brown

22

Chris가 언급했듯이 열거 형은 Android에서 훨씬 더 많은 메모리를 필요로하므로 어디에서나 계속 사용됩니다. 대신 컴파일러가 전달 된 값의 유효성을 검사하도록 주석을 사용하는 IntDef 또는 StringDef 를 시도해야 합니다.

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 연산)을 허용하는 플래그로도 사용할 수 있습니다.

편집 : 열거 형을 int로 변환하는 것이 Proguard의 기본 최적화 중 하나 인 것 같습니다 .


3
나는 int 상수를 주석 클래스에 직접 배치하는 것을 좋아합니다. 따라서 일반 열거 형처럼 보입니다. 여기에 설명했습니다. blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.


9

비디오 에 따르면 ProGuard를 사용하면 Enums 성능 문제에 대해 생각할 필요가 없습니다 !!

Proguard는 많은 상황에서 Enum을 사용자 대신 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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.