프로그래밍할 때 특정 데이터 유형에 대해 유효한 값 세트를 제한해야 하는 경우가 종종 있습니다. 예를 들어, 요일은 7개의 다른 값을 가질 수 있고, 한 해의 달은 12개, 계절은 4개를 가질 수 있습니다. 이러한 문제를 해결하기 위해 많은 정적으로 유형이 지정된 프로그래밍 언어는 특별한 데이터 유형을 제공합니다. 열거 ( Enum 멤버는
요소는 -class의
enum
). 열거형은 Java에 바로 나타나지 않았습니다. enum
버전 1.5부터 특수 언어 구성이 도입되었습니다. 지금까지 프로그래머는 열거형을 구현하기 위해 다른 방법을 사용해 왔습니다.
열거형 구성
예부터 시작해 보겠습니다.enum
다음을 사용하여 계절을 저장하기 위한 데이터 유형을 설명하겠습니다 .
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
음, 그 사용에 대한 간단한 예는 다음과 같습니다.
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
그 결과 SUMMER 가 콘솔에 인쇄됩니다 . 이 예는 명백하고 설명이 필요하지 않다고 생각합니다.
Enum은 클래스입니다.
을 선언함으로써enum
암시적으로 에서 파생된 클래스를 생성합니다 java.lang.Enum
. 일반적으로 구성 enum Season { ... }
은 class Season extends java.lang.Enum { ... }
. 컴파일러는 우리가 명시적으로 상속하는 것을 허용하지 않지만 다음을 사용하여 상속되었는지 java.lang.Enum
확인하는 것은 쉽습니다 . enum
reflection
System.out.println(Season.class.getSuperclass());
콘솔에 다음이 표시됩니다.
class java.lang.Enum
실제 상속은 Java 컴파일러에 의해 자동으로 수행됩니다. enum
다음으로, 열거형을 -class로 구현하고 열거형 유형의 가능한 값을 -a 요소로 구현하기 위해 컴파일러에서 생성한 클래스를 호출하는 데 동의하겠습니다 enum
.
Enum 멤버는 enum
정적으로 액세스할 수 있는 -class의 인스턴스입니다.
요소는 -class의 enum Season (WINTER, SPRING и т.д.)
정적으로 액세스 가능한 인스턴스입니다 . 정적 가용성을 통해 참조 비교 연산자를 사용하여 비교를 수행할 수 있습니다 . 예: enum
Season
==
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
enum 요소의 이름과 일련번호
앞서 언급했듯이 모든enum
-class는 java.lang.Enum
모든 열거에 유용한 여러 메서드를 포함하는 를 상속합니다. 예:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
출력은 다음과 같습니다:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
메소드 name()
및 toString()
는 여기에 표시됩니다 ordinal()
. 메소드의 의미는 분명합니다. enum
이러한 메서드는 클래스에서 상속된다는 점에 유의해야 합니다 java.lang.Enum
. 이름의 문자열 표현으로 요소 가져오기enum
enum
문자열 표현으로 요소를 가져오는 작업이 자주 발생합니다 . 이러한 목적을 위해 각 enum
클래스에서 컴파일러는 이름이 같은 public static EnumClass valueOf(String name)
열거형 요소를 반환하는 특별한 정적 메서드인 를 자동으로 생성합니다 . 사용 예: EnumClass
name
String name = "WINTER";
Season season = Season.valueOf(name);
코드를 실행한 결과 시즌 변수는 Season.WINTER
. 요소를 찾을 수 없으면 IllegalArgumentException이 발생하고 , name
동일 하면 NullPointerException이 발생합니다 . 그런데 이것은 종종 잊혀집니다. 어떤 이유에서인지 많은 사람들은 함수가 하나의 인수를 취하고 특정 조건에서 IllegalArgumentException을 발생시키는 경우 이를 전달하면 확실히 IllegalArgumentException 도 발생하게 될 것이라고 굳게 확신합니다 . 그러나 그것은 요점을 벗어났습니다. 계속합시다. 열거형의 모든 요소 가져오기 런타임 시 -class의 모든 요소 목록을 가져와야 하는 경우가 있습니다 . 이러한 목적을 위해 컴파일러는 각 -class 에 메서드를 생성합니다 . 사용 예: null
null
enum
enum
public static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
우리는 다음과 같은 결과를 얻습니다:
[WINTER, SPRING, SUMMER, AUTUMN]
클래스에는 메소드 valueOf()
나 메소드가 정의되어 있지 않습니다 . 대신 -class가 컴파일될 때 컴파일러에 의해 자동으로 추가됩니다 . -class 에 자신만의 메소드 추가하기 -class와 해당 요소 모두에 자신만의 메소드를 추가할 수 있는 기회가 있습니다 . 동일하지만 다형성이 있습니다. 마지막 예에서는 에서 상속을 사용하는 방법을 보여줍니다 . 이에 대해서는 나중에 자세히 설명합니다. Java 의 상속을 사용 하면 단일 인스턴스에서 생성되고 정적으로 액세스할 수 있는 개체인 클래스 계층 구조를 구현할 수 있습니다. 이 경우 요소에는 자체 생성자가 포함될 수 있습니다. 예를 들어보겠습니다. 여기서는 , 및 3개의 요소로 열거형을 선언합니다 . 컴파일러는 다음 클래스와 객체를 생성합니다. values()
java.lang.Enum
enum
enum
enum
enum
enum
enum
enum
Type
INT
INTEGER
STRING
Type
- 파생 클래스java.lang.Enum
INT
— 에서 파생된 첫 번째 클래스의 객체Type
INTEGER
— 다음에서 파생된 두 번째 클래스의 객체Type
STRING
— 다음에서 파생된 세 번째 클래스의 객체Type
Object parse(String)
다형성 메서드 와 생성자를 사용하여 세 개의 파생 클래스가 생성됩니다 Type(..., boolean)
. 동시에 클래스 및 개체는 INT
단일 복사본에 존재하며 정적으로 액세스할 수 있습니다 INTEGER
. STRING
다음을 통해 확인할 수 있습니다.
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass() + " " + Type.STRING.getClass().getSuperclass());
우리는 출력을 얻습니다:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
컴파일러가 에서 파생된 클래스 Type
와 3개의 nested
클래스를 생성한 것을 볼 수 있습니다 Type
.
상속을 통해 디컴파일된 열거형 클래스
Type
위 내용을 확인하기 위해 위 예제의 열거형을 디컴파일한 결과도 제시합니다 .
열거형과 파라메트릭 다형성
독자는 " 왜 위의 Type 열거형이 제네릭을 사용하지 않는가? " 라고 궁금해할 것입니다. 사실 Java에서는 제네릭 사용이enum
금지되어 있습니다. 따라서 다음 예제는 컴파일되지 않습니다.
enum Type<T> {}
추가 연구
Java에서 열거형이 작동하는 방식을 더 깊이 이해하려면 클래스의 소스 코드를 숙지java.lang.Enum
하고 Jad 디컴파일러를 사용하여 생성된 코드를 연구하는 것이 좋습니다. 또한 Java 라이브러리 소스 코드를 연구하는 것은 Java에서 얼마나 많은 메커니즘이 작동하는지 이해하는 데 절대적으로 필요하며 객체 지향 설계의 참고 자료로 유용합니다. 원본 출처 링크: http://alexander.lds.lg.ua/
GO TO FULL VERSION