스위치 문과 함께 열거 형을 사용하는 Java


106

나는이 질문과 비슷한 다양한 Q & A를 보았지만 해결책을 찾지 못했습니다.

내가 가진 것은 TV 가이드를 보는 다양한 방법을 나타내는 열거 형입니다.

NDroid Application클래스에서

static enum guideView {
    GUIDE_VIEW_SEVEN_DAY,
    GUIDE_VIEW_NOW_SHOWING,
    GUIDE_VIEW_ALL_TIMESLOTS
}

... 사용자가 뷰를 변경하면 이벤트 핸들러 int가 0-2에서 수신하고 다음과 같이하고 싶습니다 ...

Android Activity onClick(DialogInterface dialog, int which)이벤트 핸들러에서

// 'which' is an int from 0-2
switch (which) {
    case NDroid.guideView.GUIDE_VIEW_SEVEN_DAY:
    ...
    break;
}

위와 같은 것을 허용하는 C # 열거 형 및 select / case 문에 익숙하며 Java가 다른 작업을 수행한다는 것을 알고 있지만 수행해야 할 작업을 이해할 수 없습니다.

if진술 에 의지해야 합니까? 3 가지 선택 만있을 것이므로 할 수 있지만 Java에서 switch-case로 어떻게 할 수 있는지 궁금했습니다.

편집 죄송합니다. 저는 일반적인 Java 문제로보고 있었기 때문에 문제를 완전히 확장하지 않았습니다. 좀 더 설명하기 위해 질문에 추가했습니다.

Android에 특정한 것이 없으므로 Android로 태그를 지정하지 않았지만 열거 형은 Application클래스에 정의되어 있고 스위치를 원하지 않는 코드는 Activity. 열거 형은 여러 활동에서 액세스해야하므로 정적입니다.


1
case GUIDE_VIEW_SEVEN_DAY적절한 수입 후에 있어야합니다 . 어떤 문제가 있습니까?
Dave Newton

이벤트 처리기가 열거 형을 받도록 만들 수 없습니까? 그 외에도 도움이 될 것입니다. stackoverflow.com/questions/5292790/…
Brian Roach

@Dave : 죄송합니다. 코드를 수정하여 상태를 보여줍니다. Eclipse는 guideView에서 int로 변환 할 수 없다는 Type Mismatch 오류를 표시합니다.
Squonk

@Brian : 이것은 Android 앱이며 이벤트 핸들러 ( OnClickListener )는 DialogInterface구현해야하는 인터페이스에 의해 정의됩니다 .
Squonk

@MisterSquonk 오, int에서 얻은 것이 그리 웠습니다. 죄송합니다. Ophidian의 답변을 참조하십시오. 기능을 열거 형에 넣었지만.
Dave Newton

답변:


162

누락 된 부분은 정수에서 유형 안전 열거 형으로 변환하는 것입니다. Java는 자동으로 수행하지 않습니다. 이에 대해 몇 가지 방법이 있습니다.

  1. 형식이 안전한 열거 형 대신 정적 최종 정수 목록을 사용하고받은 int 값을 켭니다 (이는 Java 5 이전 접근 방식입니다).
  2. 지정된 id 값 ( heneryville에 설명 된대로 ) 또는 열거 형 값의 서수 값을 켭니다 . 즉guideView.GUIDE_VIEW_SEVEN_DAY.ordinal()
  3. int 값이 나타내는 열거 형 값을 확인한 다음 열거 형 값을 켭니다.

    enum GuideView {
        SEVEN_DAY,
        NOW_SHOWING,
        ALL_TIMESLOTS
    }
    
    // Working on the assumption that your int value is 
    // the ordinal value of the items in your enum
    public void onClick(DialogInterface dialog, int which) {
        // do your own bounds checking
        GuideView whichView = GuideView.values()[which];
        switch (whichView) {
            case SEVEN_DAY:
                ...
                break;
            case NOW_SHOWING:
                ...
                break;
        }
    }

    valueOf정수 값을 인수로 사용하여 적절한 열거 형 값을 해결하고 경계 검사를 중앙 집중화 할 수 있는 사용자 지정 구현 을 작성하는 것이 더 유용하거나 오류가 적을 수 있습니다.


감사합니다. 내 코드로 작업하는 데 시간이 좀 걸렸지 만 이제 게시 한 예제 코드로 잘 작동합니다. C #에서 6 년, Java에서 1 년-저를 괴롭히는 일을 자주 접하지 않습니다. 유사점이 너무 많지만 가끔 이렇게 매우 다른 경우가 있습니다. 나는 서둘러 이것을 잊지 않을 것입니다. :-)
Squonk 2011

2
case 문에 정규화되지 않은 열거 형 이름이 필요하므로 case GuideView.SEVEN_DAY:컴파일 오류가 발생합니다 case SEVEN_DAY:.
haridsv

최고야!
Neo

42

whichViewGuideView Enum의 객체 인 경우 다음이 잘 작동합니다. 이후 상수에 대한 한정자가 없습니다 case.

switch (whichView) {
    case SEVEN_DAY:
        ...
        break;
    case NOW_SHOWING:
        ...
        break;
}

4
이게 어떻게 가능해?!
Jes Chergui

12

열거 형은 보유한 것과 같이 케이스 레이블 내에서 정규화되어서는 안되며 NDroid.guideView.GUIDE_VIEW_SEVEN_DAY, 대신 자격을 제거하고 사용해야합니다.GUIDE_VIEW_SEVEN_DAY


이것을 선호합니다. 단순한!
Lazy Ninja

5

Java enum의 몇 가지 사용법을 좋아합니다.

  1. .name ()을 사용하면 문자열에서 열거 형 이름을 가져올 수 있습니다.
  2. .ordinal ()을 사용하면 0부터 시작하는 정수 값을 가져올 수 있습니다.
  3. 각 열거 형에 다른 값 매개 변수를 첨부 할 수 있습니다.
  4. 물론 스위치가 활성화됩니다.

값 매개 변수가있는 열거 형 :

    enum StateEnum {
        UNDEFINED_POLL  ( 1 * 1000L,       4 * 1000L),
        SUPPORT_POLL    ( 1 * 1000L,       5 * 1000L),
        FAST_POLL       ( 2 * 1000L,  4 * 60 * 1000L),
        NO_POLL         ( 1 * 1000L,       6 * 1000L); 
        ...
    }

스위치 예 :

private void queuePoll(StateEnum se) {
    // debug print se.name() if needed
    switch (se) {
        case UNDEFINED_POLL:
            ...
            break;
        case SUPPORT_POLL:
            ...
            break;

3

이것은 설명하는 방식으로 작동합니다. 어떤 오류가 발생합니까? 코드를 붙여 넣을 수 있다면 도움이 될 것입니다.

http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

편집 : 정적 열거 형을 정의 하시겠습니까? 그것은 나에게 옳지 않은 것 같습니다. 열거 형은 다른 객체와 매우 유사합니다. 코드가 컴파일되고 실행되지만 잘못된 결과를 제공하는 경우 아마도 이것이 그 이유 일 것입니다.


"중첩 된 열거 형 유형은 암시 적으로 정적입니다. 중첩 된 열거 형 유형을 정적으로 명시 적으로 선언 할 수 있습니다."— JLS §8.9 .
trashgod

@trashgod, 실제로-하지만 실제로는 더 분명한 IMO이므로 혼란을 피하기 위해 항상 암시 적 선언을 사용합니다. 전역 정적 열거 형 (내가 이것을 가정 한 것임)은 대부분의 경우 잘못된 것입니다.
SystemParadox 2011

2
enumerations accessing is very simple in switch case

private TYPE currentView;

//declaration of enum 
public enum TYPE {
        FIRST, SECOND, THIRD
    };

//handling in switch case
switch (getCurrentView())
        {
        case FIRST:
            break;
        case SECOND:
            break;
        case THIRD:
            break;
        }

//getter and setter of the enum
public void setCurrentView(TYPE currentView) {
        this.currentView = currentView;
    }

    public TYPE getCurrentView() {
        return currentView;
    }

//usage of setting the enum 
setCurrentView(TYPE.FIRST);

avoid the accessing of TYPE.FIRST.ordinal() it is not recommended always

외부에서 데이터를 가져 오지 않는 경우에만 작동합니다. OP가 TYPE이 아닌 값 1, 2, 3을 반환한다고 말했기 때문에 1, 2, 3을 취하고 그가 나열한 스위치 케이스로 이동하기 전에 TYPE을 리턴하는 반전 된 스위치 케이스 없이는 메소드가 작동하지 않습니다.
WORMSS

2

짧은 연관 함수 예 :

public String getIcon(TipoNotificacao tipo)
{
    switch (tipo){
        case Comentou : return "fa fa-comments";
        case ConviteEnviou : return "icon-envelope";
        case ConviteAceitou : return "fa fa-bolt";
        default: return "";
    }
}

@Dhanushka가 말했듯이 "switch"안의 한정자를 생략하는 것이 핵심입니다.


1

나는 그것을하고있다

public enum State
{
    // Retrieving, // the MediaRetriever is retrieving music //
    Stopped, // media player is stopped and not prepared to play
    Preparing, // media player is preparing...
    Playing, // playback active (media player ready!). (but the media player
                // may actually be
                // paused in this state if we don't have audio focus. But we
                // stay in this state
                // so that we know we have to resume playback once we get
                // focus back)
    Paused; // playback paused (media player ready!)

    //public final static State[] vals = State.values();//copy the values(), calling values() clones the array

};

public State getState()
{
        return mState;   
}

그리고 Switch 문에서 사용

switch (mService.getState())
{
case Stopped:
case Paused:

    playPause.setBackgroundResource(R.drawable.selplay);
    break;

case Preparing:
case Playing:

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