Java Language
열거 형
수색…
소개
enum
키워드를 사용하여 선언 된) enum
은 단일 클래스의 상당한 양의 상수에 대한 약식 구문입니다.
통사론
- [public / protected / private] enum Enum_name {// 새로운 enum을 선언합니다.
- ENUM_CONSTANT_1 [, ENUM_CONSTANT_2 ...]; // enum 상수를 선언하십시오. 이것은 enum 내부의 첫 번째 줄이어야하며 마지막에는 세미콜론과 함께 쉼표로 구분해야합니다.
- ENUM_CONSTANT_1 (param) [, ENUM_CONSTANT_2 (param) ...]; // 매개 변수로 enum 상수를 선언하십시오. 매개 변수 유형은 생성자와 일치해야합니다.
- ENUM_CONSTANT_1 {...} [, ENUM_CONSTANT_2 {...} ...]; // 재정의 된 메서드를 사용하여 enum 상수를 선언합니다. 열거 형에 추상 메소드가 포함되어 있으면이 작업을 수행해야합니다. 그러한 모든 방법을 구현해야합니다.
- ENUM_CONSTANT.name () // enum 정수의 이름을 가지는 String를 돌려줍니다.
- ENUM_CONSTANT.ordinal () //이 열거 형 상수의 서수를 반환합니다.이 열거 형 상수는 열거 형 선언의 위치이며, 초기 상수에는 0의 서수가 할당됩니다.
- Enum_name.values () // 호출 할 때마다 해당 열거 형의 모든 상수를 포함하는 새 배열 (Enum_name [] 유형)을 반환합니다.
- Enum_name.valueOf ( "ENUM_CONSTANT") // ENUM_CONSTANT.name ()의 역함 - 주어진 이름의 enum 상수를 반환합니다.
- Enum.valueOf (Enum_name.class, "ENUM_CONSTANT") // 이전의 동의어 : ENUM_CONSTANT.name ()의 역함 - 주어진 이름의 enum 상수를 반환합니다.
비고
제한 사항
열거 형은 항상 java.lang.Enum
을 확장하므로 enum이 클래스를 확장 할 수 없습니다. 그러나 많은 인터페이스를 구현할 수 있습니다.
팁 & 트릭
특수 표현으로 인해 enum을 키로 사용할 수있는보다 효율적인 맵 과 세트 가 있습니다. 이들은 종종 비 전문 기술자보다 더 빨리 실행됩니다.
기본 enum 선언 및 사용
열거 형 은 일련의 상수를 정의하기 위해 컴파일 타임에 알려진 여러 번 인스턴스화 된 봉인 된 클래스에 대한 구문 설탕으로 간주 될 수 있습니다.
다른 계절을 나열하는 간단한 열거 형은 다음과 같이 선언됩니다.
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
열거 형 상수가 모두 대문자로되어있을 필요는 없지만, 상수의 이름은 완전히 대문자이며 단어는 밑줄로 구분됩니다.
Enum을 자체 파일에 선언 할 수 있습니다.
/**
* This enum is declared in the Season.java file.
*/
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
하지만 다른 클래스에서 선언 할 수도 있습니다.
public class Day {
private Season season;
public String getSeason() {
return season.name();
}
public void setSeason(String season) {
this.season = Season.valueOf(season);
}
/**
* This enum is declared inside the Day.java file and
* cannot be accessed outside because it's declared as private.
*/
private enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
마지막으로 메소드 몸체 또는 생성자 안에 Enum을 선언 할 수 없습니다.
public class Day {
/**
* Constructor
*/
public Day() {
// Illegal. Compilation error
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
}
public void aSimpleMethod() {
// Legal. You can declare a primitive (or an Object) inside a method. Compile!
int primitiveInt = 42;
// Illegal. Compilation error.
enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
Season season = Season.SPRING;
}
}
중복 열거 형 상수는 허용되지 않습니다.
public enum Season {
WINTER,
WINTER, //Compile Time Error : Duplicate Constants
SPRING,
SUMMER,
FALL
}
enum의 모든 상수는 기본적으로 public
, static
및 final
입니다. 모든 상수는 static
이므로 열거 형 이름을 사용하여 직접 액세스 할 수 있습니다.
열거 형 상수는 메소드 매개 변수로 전달 될 수 있습니다.
public static void display(Season s) {
System.out.println(s.name()); // name() is a built-in method that gets the exact name of the enum constant
}
display(Season.WINTER); // Prints out "WINTER"
values()
메서드를 사용하여 열거 형 상수의 배열을 가져올 수 있습니다. 값은 반환 된 배열에서 선언 순서가되도록 보장됩니다.
Season[] seasons = Season.values();
주 :이 메소드는, 불려 갈 때마다 새로운 값의 배열을 할당합니다.
열거 형 상수를 반복하려면 다음을 수행하십시오.
public static void enumIterate() {
for (Season s : Season.values()) {
System.out.println(s.name());
}
}
switch
문에서 enum을 사용할 수 있습니다.
public static void enumSwitchExample(Season s) {
switch(s) {
case WINTER:
System.out.println("It's pretty cold");
break;
case SPRING:
System.out.println("It's warming up");
break;
case SUMMER:
System.out.println("It's pretty hot");
break;
case FALL:
System.out.println("It's cooling down");
break;
}
}
==
사용하여 열거 형 상수를 비교할 수도 있습니다.
Season.FALL == Season.WINTER // false
Season.SPRING == Season.SPRING // true
열거 형 상수를 비교하는 또 다른 방법은 다음과 같이 함정에 쉽게 빠질 수있는 나쁜 연습으로 간주되는 equals()
를 사용하는 것입니다.
Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error
게다가 enum
에있는 인스턴스 집합은 런타임에 변경할 수 없지만 인스턴스 자체는 본질적으로 변경되지 않습니다. 왜냐하면 다른 클래스와 마찬가지로 enum
은 아래에 설명 된 것처럼 변경할 수있는 필드를 포함 할 수 있기 때문입니다.
public enum MutableExample {
A,
B;
private int count = 0;
public void increment() {
count++;
}
public void print() {
System.out.println("The count of " + name() + " is " + count);
}
}
// Usage:
MutableExample.A.print(); // Outputs 0
MutableExample.A.increment();
MutableExample.A.print(); // Outputs 1 -- we've changed a field
MutableExample.B.print(); // Outputs 0 -- another instance remains unchanged
그러나 좋은 예는 enum
인스턴스를 변경 불가능하게 만드는 것입니다. 즉, 필드에 추가 필드가 없거나 모든 필드가 final
로 표시되고 불변 인 경우입니다. 이렇게하면 응용 프로그램의 수명 동안 enum
이 메모리를 누설하지 않으며 모든 스레드에서 해당 인스턴스를 사용하는 것이 안전하다는 것을 보장합니다.
열거 형은 Enum
클래스가 수행하기 때문에 Serializable
및 Comparable
암시 적으로 구현합니다.
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable
생성자와 함께 열거 형
enum
은 public 생성자를 가질 수 없습니다. 그러나 private 생성자는 허용 가능합니다 (enum의 생성자는 기본적으로 package-private입니다 ).
public enum Coin {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25); // usual names for US coins
// note that the above parentheses and the constructor arguments match
private int value;
Coin(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
int p = Coin.NICKEL.getValue(); // the int value will be 5
열거 형에 대한 인스턴스 수가 제한되어 있으므로 모든 필드를 비공개로 유지하고 getter 메서드를 제공하는 것이 좋습니다.
Enum
을 대신 class
로 구현하면 다음과 같이 보입니다.
public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{
public static final Coin PENNY = new Coin(1);
public static final Coin NICKEL = new Coin(5);
public static final Coin DIME = new Coin(10);
public static final Coin QUARTER = new Coin(25);
private int value;
private Coin(int value){
this.value = value;
}
public int getValue() {
return value;
}
}
int p = Coin.NICKEL.getValue(); // the int value will be 5
열거 형 상수는 기술적으로 변경할 수 있으므로 열거 형 상수의 내부 구조를 변경하기 위해 설정자가 추가 될 수 있습니다. 그러나 이것은 매우 나쁜 실행으로 간주되므로 피해야합니다.
가장 좋은 방법은 final
Enum 필드를 변경하지 못하게하는 것입니다.
public enum Coin {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
private final int value;
Coin(int value){
this.value = value;
}
...
}
같은 열거 형에 여러 생성자를 정의 할 수 있습니다. 당신이 할 때, 귀하의 enum 선언에 전달 인자는 호출되는 생성자를 결정합니다 :
public enum Coin {
PENNY(1, true), NICKEL(5, false), DIME(10), QUARTER(25);
private final int value;
private final boolean isCopperColored;
Coin(int value){
this(value, false);
}
Coin(int value, boolean isCopperColored){
this.value = value;
this.isCopperColored = isCopperColored;
}
...
}
주 : Enum
클래스가하기 (위해) 때문에, 모든 원시적이 아닌 enum 필드는 Serializable
를 구현할 필요가 있습니다.
메소드 및 정적 블록 사용
열거 형은 모든 클래스와 마찬가지로 메소드를 포함 할 수 있습니다. 이것이 어떻게 작동하는지 보려면 다음과 같이 enum을 선언하십시오.
public enum Direction {
NORTH, SOUTH, EAST, WEST;
}
열거 형을 반대 방향으로 반환하는 메서드가 있습니다.
public enum Direction {
NORTH, SOUTH, EAST, WEST;
public Direction getOpposite(){
switch (this){
case NORTH:
return SOUTH;
case SOUTH:
return NORTH;
case WEST:
return EAST;
case EAST:
return WEST;
default: //This will never happen
return null;
}
}
}
이것은 필드와 정적 이니셜 라이저 블록을 사용하여 더 향상 될 수 있습니다.
public enum Direction {
NORTH, SOUTH, EAST, WEST;
private Direction opposite;
public Direction getOpposite(){
return opposite;
}
static {
NORTH.opposite = SOUTH;
SOUTH.opposite = NORTH;
WEST.opposite = EAST;
EAST.opposite = WEST;
}
}
이러한 예에서, 역방향은 전용 인스턴스 필드에 저장된 opposite
정적 처음 초기화되고, Direction
사용된다. (때문에 특별한 경우 NORTH
참조 SOUTH
반대로)을, 우리는 사용할 수 없습니다 생성자와 열거 형 여기 (생성자 NORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST)
더 우아한 것 허용 할 opposite
에 final
으로 선언되었지만 자기 참조적일 수 있으므로 허용되지 않습니다).
인터페이스 구현
이 enum
은 미리 컴파일 된 정규식 패턴에 대해 String
입력을 테스트하는 호출 가능 함수이기도합니다.
import java.util.function.Predicate;
import java.util.regex.Pattern;
enum RegEx implements Predicate<String> {
UPPER("[A-Z]+"), LOWER("[a-z]+"), NUMERIC("[+-]?[0-9]+");
private final Pattern pattern;
private RegEx(final String pattern) {
this.pattern = Pattern.compile(pattern);
}
@Override
public boolean test(final String input) {
return this.pattern.matcher(input).matches();
}
}
public class Main {
public static void main(String[] args) {
System.out.println(RegEx.UPPER.test("ABC"));
System.out.println(RegEx.LOWER.test("abc"));
System.out.println(RegEx.NUMERIC.test("+111"));
}
}
열거 형의 각 멤버는 메서드를 구현할 수도 있습니다.
import java.util.function.Predicate;
enum Acceptor implements Predicate<String> {
NULL {
@Override
public boolean test(String s) { return s == null; }
},
EMPTY {
@Override
public boolean test(String s) { return s.equals(""); }
},
NULL_OR_EMPTY {
@Override
public boolean test(String s) { return NULL.test(s) || EMPTY.test(s); }
};
}
public class Main {
public static void main(String[] args) {
System.out.println(Acceptor.NULL.test(null)); // true
System.out.println(Acceptor.EMPTY.test("")); // true
System.out.println(Acceptor.NULL_OR_EMPTY.test(" ")); // false
}
}
열거 다형 패턴
이 방법의 "확장"세트에 동의 할 필요가있을 때 enum
값, 프로그래머는 통상에서와 같은 다형을 적용 할 수있는 class
를 Where anywere 사용될 인터페이스 만들어 enum
들을 사용한다 :
public interface ExtensibleEnum {
String name();
}
이 방법으로, 인터페이스에 의해 태그 화 된 ( enum
) 모든 enum
매개 변수로 사용할 수 있으므로 프로그래머는 메소드에서 허용되는 다양한 양의 enum
을 작성할 수 있습니다. 예를 들어 기본 (변경 불가능한) enum
이있는 API에서 유용 할 수 있으며 이러한 API 사용자는 더 많은 값으로 enum
을 "확장"하려고합니다.
기본 enum 값 집합은 다음과 같이 정의 할 수 있습니다.
public enum DefaultValues implements ExtensibleEnum {
VALUE_ONE, VALUE_TWO;
}
그런 다음 추가 값을 다음과 같이 정의 할 수 있습니다.
public enum ExtendedValues implements ExtensibleEnum {
VALUE_THREE, VALUE_FOUR;
}
열거 형을 사용하는 방법을 보여주는 샘플 - printEnum()
이 두 enum
모두의 값을 허용하는 방법에 유의하십시오.
private void printEnum(ExtensibleEnum val) {
System.out.println(val.name());
}
printEnum(DefaultValues.VALUE_ONE); // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO); // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR); // VALUE_FOUR
참고 :이 패턴은 다른 열거 형에서 이미 하나의 열거 형에 정의 된 열거 형 값을 재정의하는 것을 방해하지 않습니다. 이러한 enum 값은 다른 인스턴스가됩니다. 또한 switch-on-enum은 실제 enum
아닌 인터페이스이기 때문에 사용할 수 없습니다.
추상 메서드로 열거 형
열거 형은 각 enum
멤버가 구현해야하는 추상 메서드를 정의 할 수 있습니다.
enum Action {
DODGE {
public boolean execute(Player player) {
return player.isAttacking();
}
},
ATTACK {
public boolean execute(Player player) {
return player.hasWeapon();
}
},
JUMP {
public boolean execute(Player player) {
return player.getCoordinates().equals(new Coordinates(0, 0));
}
};
public abstract boolean execute(Player player);
}
이렇게하면 각 열거 형 멤버가 최상위 수준 정의의 메서드에서 형식을 전환하지 않고도 지정된 작업에 대한 고유 한 동작을 정의 할 수 있습니다.
이 패턴은 다형성 및 / 또는 구현 인터페이스를 사용하여 일반적으로 달성되는 간단한 형태입니다.
enums 문서화
항상 enum
이름이 이해 될 정도로 명확하지는 않습니다. enum
을 문서화하려면 표준 javadoc을 사용하십시오.
/**
* United States coins
*/
public enum Coins {
/**
* One-cent coin, commonly known as a penny,
* is a unit of currency equaling one-hundredth
* of a United States dollar
*/
PENNY(1),
/**
* A nickel is a five-cent coin equaling
* five-hundredth of a United States dollar
*/
NICKEL(5),
/**
* The dime is a ten-cent coin refers to
* one tenth of a United States dollar
*/
DIME(10),
/**
* The quarter is a US coin worth 25 cents,
* one-fourth of a United States dollar
*/
QUARTER(25);
private int value;
Coins(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
열거 형 값 가져 오기
각 enum 클래스에는 values()
라는 암시 적 정적 메서드가 포함되어 있습니다. 이 메서드는 해당 열거 형의 모든 값을 포함하는 배열을 반환합니다. 이 메서드를 사용하여 값을 반복 할 수 있습니다. 그러나이 메서드는 호출 될 때마다 새 배열을 반환한다는 점에 유의해야합니다.
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
/**
* Print out all the values in this enum.
*/
public static void printAllDays() {
for(Day day : Day.values()) {
System.out.println(day.name());
}
}
}
Set
가 필요하면 EnumSet.allOf(Day.class)
도 사용할 수 있습니다.
바운드 형식 매개 변수로서의 열거 형
generics를 사용하여 java 클래스를 작성할 때 type 매개 변수가 enum인지 확인하는 것이 가능합니다. 모든 열거 형은 Enum
클래스를 확장하므로 다음 구문을 사용할 수 있습니다.
public class Holder<T extends Enum<T>> {
public final T value;
public Holder(T init) {
this.value = init;
}
}
이 예에서 T
유형은 열거 형 이어야합니다 .
이름으로 열거 형을 가져옵니다.
열거 형 DayOfWeek
가 있다고 가정 DayOfWeek
.
enum DayOfWeek {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}
열거 형은 내장 된 정적 valueOf()
메소드로 컴파일됩니다.이 메소드는 이름으로 상수를 조회하는 데 사용할 수 있습니다.
String dayName = DayOfWeek.SUNDAY.name();
assert dayName.equals("SUNDAY");
DayOfWeek day = DayOfWeek.valueOf(dayName);
assert day == DayOfWeek.SUNDAY;
이것은 또한 동적 enum 유형을 사용하여 가능합니다.
Class<DayOfWeek> enumType = DayOfWeek.class;
DayOfWeek day = Enum.valueOf(enumType, "SUNDAY");
assert day == DayOfWeek.SUNDAY;
지정된 enum에 일치하는 이름을 가지는 정수가없는 경우, 이러한 valueOf()
Methods는 모두 IllegalArgumentException
합니다.
Guava 라이브러리는 명시 적 예외 처리를 제거하기 위해 Guava Optional
을 반환하는 도우미 메서드 Enums.getIfPresent()
를 제공합니다.
DayOfWeek defaultDay = DayOfWeek.SUNDAY;
DayOfWeek day = Enums.valueOf(DayOfWeek.class, "INVALID").or(defaultDay);
assert day == DayOfWeek.SUNDAY;
단일 요소 열거 형을 사용하여 싱글 톤 패턴 구현
열거 형 상수는 열거 형을 처음 참조 할 때 인스턴스화됩니다. 따라서 단일 요소 열거 형을 사용하여 Singleton 소프트웨어 디자인 패턴을 구현할 수 있습니다.
public enum Attendant {
INSTANCE;
private Attendant() {
// perform some initialization routine
}
public void sayHello() {
System.out.println("Hello!");
}
}
public class Main {
public static void main(String... args) {
Attendant.INSTANCE.sayHello();// instantiated at this point
}
}
Joshua Bloch의 "Effective Java"서적에 따르면 단일 요소 열거 형은 싱글 톤을 구현하는 가장 좋은 방법입니다. 이 접근법에는 다음과 같은 장점이 있습니다.
- 스레드 안전성
- 단일 인스턴스화의 보장
- out-of-the-box 직렬화
그리고 인터페이스를 구현 하는 섹션에서 볼 수 있듯이이 싱글 톤은 하나 이상의 인터페이스를 구현할 수도 있습니다.
속성 (필드)이있는 열거 형
우리가 더 많은 정보와 함께 상수 값이 아닌 enum
을 사용하고자 할 때, 우리는 두 개의 enum을 비교할 수 있기를 원합니다.
다음 예제를 고려하십시오.
public enum Coin {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
private final int value;
Coin(int value){
this.value = value;
}
public boolean isGreaterThan(Coin other){
return this.value > other.value;
}
}
여기서 우리는 그 가치를 나타내는 Coin
이라는 Enum
을 정의했습니다. isGreaterThan
메서드를 사용하면 두 개의 enum
비교할 수 있습니다.
Coin penny = Coin.PENNY;
Coin dime = Coin.DIME;
System.out.println(penny.isGreaterThan(dime)); // prints: false
System.out.println(dime.isGreaterThan(penny)); // prints: true
enum을 String으로 변환하십시오.
때로는 열거 형을 String으로 변환하고 싶을 때가 있습니다. 두 가지 방법이 있습니다.
우리가 가지고 있다고 가정하자.
public enum Fruit {
APPLE, ORANGE, STRAWBERRY, BANANA, LEMON, GRAPE_FRUIT;
}
그래서 우리는 Fruit.APPLE
같은 것을 어떻게 변환합니까? "APPLE"
Fruit.APPLE
은 무엇입니까?
name()
사용하여 변환 name()
name()
은 enum
의 String
표현을 반환하는 enum
의 내부 메서드이며 반환 String
은 열거 형 값이 정의 된 방식을 정확하게 나타냅니다.
예 :
System.out.println(Fruit.BANANA.name()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"
toString()
사용하여 변환
toString()
은 기본적 으로 name()
과 동일한 비헤이비어를 갖도록 재정의됩니다.
다만, 개발자 가 toString()
를 오버라이드 (override toString()
해,보다 유저에게 친숙한 String
인쇄 할 가능성이 있습니다
코드를 검사하려면
toString()
사용하지 마십시오.name()
은 훨씬 안정적입니다. 값을 로그 또는 표준 출력 또는 다른 것으로 출력 할 때만toString()
사용하십시오.
기본적으로:
System.out.println(Fruit.BANANA.toString()); // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"
재정의되는 예
System.out.println(Fruit.BANANA.toString()); // "Banana"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "Grape Fruit"
열거 상수 특정 본문
에서 enum
특정 상수에 대한 특정 동작을 정의 할 수있다 enum
의 기본 동작에 우선 enum
이 기술은 일정한 특정 기관으로 알려져있다.
세 명의 피아노 학생, John, Ben 및 Luke가 다음과 같이 PianoClass
라는 enum
정의되어 있다고 가정합니다.
enum PianoClass {
JOHN, BEN, LUKE;
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
그리고 언젠가 다른 두 명의 학생들이 도착합니다 - 리타와 탐 - 이전의 것과 일치하지 않는 성 (여자)과 레벨 (중급) :
enum PianoClass2 {
JOHN, BEN, LUKE, RITA, TOM;
public String getSex() {
return "Male"; // issue, Rita is a female
}
public String getLevel() {
return "Beginner"; // issue, Tom is an intermediate student
}
}
그래서 새로운 학생을 상수 선언에 단순히 추가하는 것은 다음과 같이 정확하지 않습니다.
PianoClass2 tom = PianoClass2.TOM;
PianoClass2 rita = PianoClass2.RITA;
System.out.println(tom.getLevel()); // prints Beginner -> wrong Tom's not a beginner
System.out.println(rita.getSex()); // prints Male -> wrong Rita's not a male
PianoClass2
기본 동작을 다음과 같이 재정의하는 Rita 및 Tom의 상수에 대해 특정 동작을 정의 할 수 있습니다.
enum PianoClass3 {
JOHN, BEN, LUKE,
RITA {
@Override
public String getSex() {
return "Female";
}
},
TOM {
@Override
public String getLevel() {
return "Intermediate";
}
};
public String getSex() {
return "Male";
}
public String getLevel() {
return "Beginner";
}
}
지금 Tom의 레벨과 Rita의 섹스는 다음과 같아야합니다.
PianoClass3 tom = PianoClass3.TOM;
PianoClass3 rita = PianoClass3.RITA;
System.out.println(tom.getLevel()); // prints Intermediate
System.out.println(rita.getSex()); // prints Female
콘텐츠 특정 본문을 정의하는 또 다른 방법은 생성자를 사용하는 것입니다. 예를 들면 다음과 같습니다.
enum Friend {
MAT("Male"),
JOHN("Male"),
JANE("Female");
private String gender;
Friend(String gender) {
this.gender = gender;
}
public String getGender() {
return this.gender;
}
}
및 사용 :
Friend mat = Friend.MAT;
Friend john = Friend.JOHN;
Friend jane = Friend.JANE;
System.out.println(mat.getGender()); // Male
System.out.println(john.getGender()); // Male
System.out.println(jane.getGender()); // Female
0 인스턴스 enum
enum Util {
/* No instances */;
public static int clamp(int min, int max, int i) {
return Math.min(Math.max(i, min), max);
}
// other utility methods...
}
싱글 톤 (1 인스턴스 클래스)에 enum
사용할 수있는 것처럼 유틸리티 클래스 (0 인스턴스 클래스)에도 사용할 수 있습니다. 그냥 열거 형 상수의 (비어있는) 목록을 a ;
.
개인 생성자 와 비교하여 프로 및 토론에 대한 토론을 위해 인스턴스 생성 을 방지하기위한 제로 인스턴스 enum 대 private 생성자에 대한 질문을 참조하십시오.
정적 필드가있는 열거 형
enum 클래스에 정적 필드가 있어야하는 경우 열거 형 값 자체 뒤에 생성된다는 점에 유의하십시오. 즉, 다음 코드는 NullPointerException
을 발생시킵니다.
enum Example {
ONE(1), TWO(2);
static Map<String, Integer> integers = new HashMap<>();
private Example(int value) {
integers.put(this.name(), value);
}
}
이 문제를 해결할 수있는 방법은 다음과 같습니다.
enum Example {
ONE(1), TWO(2);
static Map<String, Integer> integers;
private Example(int value) {
putValue(this.name(), value);
}
private static void putValue(String name, int value) {
if (integers == null)
integers = new HashMap<>();
integers.put(name, value);
}
}
정적 필드를 초기화하지 마십시오.
enum Example {
ONE(1), TWO(2);
// after initialisisation integers is null!!
static Map<String, Integer> integers = null;
private Example(int value) {
putValue(this.name(), value);
}
private static void putValue(String name, int value) {
if (integers == null)
integers = new HashMap<>();
integers.put(name, value);
}
// !!this may lead to null poiner exception!!
public int getValue(){
return (Example.integers.get(this.name()));
}
}
초기화 :
- enum 값을 만든다.
- 부작용으로 putValue ()가 호출되어 정수가 초기화됩니다.
- 정적 값이 설정됩니다.
- 정수 = null; // 열거 형 뒤에 실행되어 정수의 내용이 손실됩니다.
열거 형 값을 비교 및 포함합니다.
열거 형은 상수 만 포함하고 ==
와 직접 비교할 수 있습니다. 따라서, 참조 검사 만 필요하며 .equals
메서드를 사용할 필요가 없습니다. 또한 .equals
잘못 사용되면 NullPointerException
하지만 이는 ==
check .equals
.
enum Day {
GOOD, AVERAGE, WORST;
}
public class Test {
public static void main(String[] args) {
Day day = null;
if (day.equals(Day.GOOD)) {//NullPointerException!
System.out.println("Good Day!");
}
if (day == Day.GOOD) {//Always use == to compare enum
System.out.println("Good Day!");
}
}
}
EnumSet
클래스를 그룹핑, 보완, 범위 지정하려면 EnumSet
클래스에 다른 메소드가 포함되어 있어야합니다.
EnumSet#range
: 두 끝점에서 정의한 범위에 따라 열거 형의 하위 집합을 가져 오려면EnumSet#of
: 범위가없는 특정 열거 형 집합입니다. 여러 가지 오버로드of
메소드가 있습니다.EnumSet#complementOf
: 메소드 매개 변수에서 제공된 enum 값을 보완하는 enum 세트enum Page { A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 } public class Test { public static void main(String[] args) { EnumSet<Page> range = EnumSet.range(Page.A1, Page.A5); if (range.contains(Page.A4)) { System.out.println("Range contains A4"); } EnumSet<Page> of = EnumSet.of(Page.A1, Page.A5, Page.A3); if (of.contains(Page.A1)) { System.out.println("Of contains A1"); } } }