enum (이전 방식, 개념, 동작방식, 사용예제, 관련메소드)

2021. 3. 19. 18:16 JAVA/Java

참조문서 : https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html

1. enum 이란?

enumeration의 앞글자로 열거라는 뜻이다. JDK 1.5 부터 관련이 있는 상수들의 집합을 사용할 때 enum을 사용한다. enum은 완전한 클래스이다. 그 이전에는 열거형 상수를 선언하려면 다음과 같이 했다.

  • 클래스 내에 final static 로 변수 선언
  • interface 에 상수선언

기존방식의 문제

  • 한 클래스에 final static 으로 다 선언하자니 네임충돌 발생할 수도 있고, 복잡함
  • 인터페이스를 사용하면 위 문제는 해결되나, 타입안정성이 떨어짐 (컴파일 때 형검사를 하지 않으므로 오류발생 소지)

enum의 장점

  • 코드가 단순해지고, 가독성이 짱
  • 인스턴스 생성과 상속을 방지하여 상수값의 타입안정성이 보장 (컴파일 때 체크)
  • enum 키워드를 사용해서 구현의 의도가 열거임을 분명히 나타냄

2. enum의 내부적인 동작방식

하지만 겉으로 코드로 보기에 깔끔하다는 것이지, enum 클래스의 내부 동작을 보면 오버헤드가 기존방식과 다를 바 없이 크다ㅋㅋ 이는 바이트코드를 보면 알 수 있었다.

// BoyFriend .java
public enum BoyFriend {
    REDBOY,
    BLUEBOY,
    BLACKBOY;
}

// javap BoyFriend.class
C:\Users\devljh\Desktop>javap BoyFriend.class
Compiled from "BoyFriend.java"
public final class BoyFriend extends java.lang.Enum<BoyFriend> {
  public static final BoyFriend REDBOY;
  public static final BoyFriend BLUEBOY;
  public static final BoyFriend BLACKBOY;
  public static BoyFriend[] values();
  public static BoyFriend valueOf(java.lang.String);
  static {};
}

// javap -c 로 자세히 까보면 스태틱 영역에서 동작 Main 변수를 초기화 하는 부분이 보인다.
 static {};
    Code:
       0: new           #4                  // class BoyFriend
       3: dup
       4: ldc           #7                  // String REDBOY
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #9                  // Field REDBOY:LBoyFriend;

이를 통해 결국은 클래스 내부에 public static final BoyFriend REDBOY = new BoyFriend(); 하는 것을 알 수 있다.

3. enum 사용하기

enum 은 클래스처럼 사용하거나 내부에서 사용될 수 있다.

  • enum 만 선언해서 클래스처럼 사용
  • 클래스 내부에 enum 을 내부클래스처럼 사용

3-1. 추가 속성 부여

상수에 괄호열고, 아래 예제처럼 파라미터 주듯이 써주면 된다. 그 아래에는 멤버변수와 생성자, getter가 있다. 예제부터 보자.

public enum BoyFriend {
	REDBOY("111", "devljh"),
	BLUEBOY("222", "powerman"),
	BLACKBOY("333", "goodgame");
	
	private String id;
	private String nickname;

	Section(String id, String nickname) {
		this.id = id;
		this.nickname= nickname;
	}

	public String getId() {
		return id;
	}

	public String getNickname() {
		return nickname;
	}
}

멤버변수가 4개이므로, 괄호 안 파라미터도 4개이다. 각 파라미터는 생성자에서 set되며, getter 메소드로 불러올 수 있다.

3-2. 생성자

enum의 생성자는 private 이다. private를 명시해주면 인텔리제이에서는 불필요하다고 검은 줄도 뜨는듯?? public으로 쓰면 빨간 줄뜬다. 이건 아니된다고!!

enum은 컴파일타임에 모든 값을 알아야 하고, 런타임 때 동적으로 어떤 값을 정해줄 수 없다. 그러므로 new할 수도 없고, public으로 접근해서도 안되니 private 생성자 밖에 안되는 것이다.

4. 관련 static 메소드

메소드명 설명
valueOf(String) String 값을 enum에서 가져옴
valueOf(Class, String) 넘겨받은 class에서 String찾아, enum에 가져옴
values() enum의 요소들을 순서대로 enum타입의 배열로 리턴.



출처: https://sjh836.tistory.com/134?category=679845 [빨간색코딩]