Java 열거형과 공개 정적 최종 필드가 있는 클래스의 장점은 무엇입니까?
나는 C#에 매우 익숙하지만 자바에서 더 일하기 시작했다.Java의 enum이 기본적으로 C#의 enum과 동등하다는 것을 알게 될 것으로 기대했지만, 이것은 사실이 아닌 것 같습니다.처음에는 Java Enum이 여러 개의 데이터를 포함할 수 있다는 것을 알고 매우 기뻤습니다(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)).단, 그 후 C#에서는 특정 값을 쉽게 할당할 수 있는 기능이나 결과적으로 충분한 노력 없이 정수를 열거형으로 변환할 수 있는 기능(즉, 정수를 Java Enum과 일치하는 값으로 변환) 등 사소한 기능이 많이 누락되어 있음을 알게 되었습니다.
그래서 질문입니다. Java enum에 대해 퍼블릭 스태틱 최종 필드가 여러 개 있는 클래스에서 어떤 이점이 있습니까?아니면 좀 더 콤팩트한 구문만 제공하는 건가요?
EDIT: 좀 더 명확히 합시다.자바 enums는 같은 유형의 퍼블릭 스태틱 최종 필드가 여러 개 있는 클래스에 비해 어떤 이점이 있습니까?예를 들어 첫 번째 링크의 행성 예제에서는 다음과 같은 공용 상수가 있는 클래스에 비해 열거형의 이점은 무엇입니까?
public static final Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
public static final Planet VENUS = new Planet(4.869e+24, 6.0518e6);
public static final Planet EARTH = new Planet(5.976e+24, 6.37814e6);
public static final Planet MARS = new Planet(6.421e+23, 3.3972e6);
public static final Planet JUPITER = new Planet(1.9e+27, 7.1492e7);
public static final Planet SATURN = new Planet(5.688e+26, 6.0268e7);
public static final Planet URANUS = new Planet(8.686e+25, 2.5559e7);
public static final Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);
내가 말할 수 있는 한, 카사블랑카의 대답은 이것을 만족시키는 유일한 것이다.
- 안전 유형을 지정하고 안전을 중시하십시오.
- 보증 싱글톤.
- 메서드를 정의 및 재정의할 수 있습니다.
- 의 할 수 .
switch
「」case
조건 없는 진술 - 「」를한 값의 삽입 시퀀셜라이제이션에 값:
ordinal().
- 값이 아닌 이름에 의한 시리얼라이제이션으로 장래에 대비할 수 있습니다.
EnumSet
★★★★★★★★★★★★★★★★★」EnumMap
를 클릭합니다
엄밀히 말하면 enum을 다수의 입력된 상수가 있는 클래스로 볼 수 있으며, 이것이 실제로 열거 상수가 내부적으로 구현되는 방법입니다.「」의 enum
단, 다음과 같은 편리한 메서드(Enum javadoc)를 제공합니다.Enum.valueOf
.
도 그것을 할 수 있는 는 언급하지 .switch
술서,,,그그그그다
에 의해, 임의의 을, 사용법을 사용하지 할 수 .instanceof
수 있습니다.if
시퀀스 또는 비문자열/int 스위칭 값.이치노
주된 장점은 타입의 안전성입니다.상수 집합을 사용하면 동일한 고유 유형의 값을 사용하여 오류를 발생시킬 수 있습니다.열거형에서는 해당 값만 사용할 수 있습니다.
예를들면
public static final int SIZE_SMALL = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE = 3;
public void setSize(int newSize) { ... }
obj.setSize(15); // Compiles but likely to fail later
대
public enum Size { SMALL, MEDIUM, LARGE };
public void setSize(Size s) { ... }
obj.setSize( ? ); // Can't even express the above example with an enum
혼란이 덜하다.예를 들어보자.이 파일에는 다음 이름을 사용하는 생성자가 있습니다.Font
, 그 스타일new Font(String, int, int)
지금까지도 스타일이나 사이즈가 먼저인지 기억이 나지 않습니다. ifFont
had를 사용중enum
문체(?PLAIN
,BOLD
,ITALIC
,BOLD_ITALIC
컨스트럭터는 다음과 같습니다.Font(String, Style, int)
혼동을 방지합니다.★★★★★★★★★★★★★★★★★★★.enum
없을 때는 Font
클래스가 생성되어 Java는 역호환성을 유지해야 하기 때문에 항상 이 애매모호함에 시달리게 됩니다.
은 단지 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.enum
public static final
상수를 지정합니다.또한 Enum은 싱글톤 및 기본 동작을 구현하는 데에도 적합하며 나중에 사용자 지정(즉, 전략 패턴)이 가능합니다.후자의 예는 다음과 같습니다.java.nio.file
및 : 개발자가 자신의 비표준을 작성하려는 경우OpenOption
할 수 있어요
여기에는 많은 좋은 답변이 있지만, 특히 enum에 맞게 최적화된 Collection API 클래스/인터페이스가 구현되어 있다는 것은 언급되지 않았습니다.
only 、 음 、 음 、 음 、 these 、 。Enum
( 「」)EnumMap
을 받아들이다Enum
키로서만) 및 가능한 경우 구현 시 컴팩트한 표현과 비트 조작으로 돌아갑니다.
이것은 무엇을 의미합니까?
우리의 ★★★★★★★★★★★★★★★★★.Enum
의 요소 유형)가(대부분 64개).Enum
이 합니다.)의의 「예」, 「예」에 저장합니다. 구현은 요소를 단일에 저장합니다.long
, 각 ", " "Enum
는 이 길이의 .long
추가EnumSet
단순히 적절한 비트를 1로 설정하고 삭제하면 해당 비트를 0으로 설정하는 것입니다. the testing testing testing 。Set
하나의 비트마스크 테스트일 뿐입니다!이제 넌 사랑해야 해Enum
이거다!
예:
public class CurrencyDenom {
public static final int PENNY = 1;
public static final int NICKLE = 5;
public static final int DIME = 10;
public static final int QUARTER = 25;}
자바 상수의 제한
1) 형식-안전 없음:우선, 이것은 타입 세이프가 아닙니다.예를 들어, 유효한 int 값을 int에 할당할 수 있습니다.그 값을 나타내는 코인은 없습니다.
2) 의미 있는 인쇄 없음: 이러한 상수의 인쇄 값은 의미 있는 코인 이름 대신 수치로 인쇄됩니다.예를 들어, NIKLE을 인쇄하면 "NIKLE" 대신 "5"로 인쇄됩니다.
3) 이름공간 없음: currencyDenom 상수에 액세스하려면 클래스 이름 앞에 프레픽스를 붙여야 합니다.CurrencyDenom.PENIY를 사용하는 것뿐만 아니라 JDK 1.5에서 정적 Import를 사용하는 것도 가능합니다.
열거의 장점
1) Java의 Enum은 type-safe이며 자체 이름 공간이 있습니다.즉, 열거형은 아래 예에서 "통화"와 같은 유형을 가지며 열거 상수에 지정된 값 이외의 값을 할당할 수 없습니다.
public enum Currency {PENNY, NICKLE, DIME, QUARTER};
Currency coin = Currency.PENNY; coin = 1; //compilation error
2) Java Enum은 클래스나 인터페이스와 같은 참조 유형이며, Java Enum 내에서 생성자, 메서드, 변수를 정의할 수 있으므로 Java Enum 유형의 다음 예시와 같이 C 및 C++의 Enum보다 강력합니다.
3) 다음 예시와 같이 열거 상수의 값을 지정할 수 있습니다.public enum Currency {PENNY(1), NICLE(5), DIME(10), QUARTER(25)}. 단, PENI(1)가 실제로 int 값을 받아들이는 컨스트럭터를 호출하고 있기 때문에 이 작업을 수행하려면 멤버 변수와 컨스트럭터를 정의해야 합니다.다음 예를 참조하십시오.
public enum Currency {
PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
private int value;
private Currency(int value) {
this.value = value;
}
};
참고 자료: https://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html
enum의 첫 번째 장점은 이미 알고 있듯이 구문의 단순성입니다.그러나 enums의 요점은 기본적으로 범위를 형성하고 유형 및 값 안전 검사를 통해 보다 포괄적인 코드 분석을 수행하는 데 도움이 되는 잘 알려진 상수 집합을 제공하는 것입니다.
enums의 이러한 속성은 프로그래머와 컴파일러 모두에 도움이 됩니다.예를 들어, 정수를 받아들이는 함수가 있다고 가정합니다.그 정수가 무슨 뜻일까요?어떤 가치관을 전달할 수 있습니까?당장 알 수 있는 건 아니잖아요.그러나 enum을 받아들이는 함수는 전달 가능한 모든 값을 매우 잘 알고 있습니다.
컴파일러의 경우 enums는 값의 범위를 결정하는 데 도움이 되며 열거형 멤버에 특별한 값을 할당하지 않는 한 0 이상입니다.이를 통해 유형 안전 검사 등을 통해 코드의 오류를 자동으로 추적할 수 있습니다.예를 들어 컴파일러는 switch 스테이트먼트에서 가능한 모든 열거값을 처리하지 않는다고 경고할 수 있습니다(즉, 다음과 같은 경우).default
n개의 열거값 중 1개만 처리합니다.또한 열거형 값의 범위가 정수보다 작기 때문에 임의 정수를 열거형으로 변환할 때 실제로 정수를 받아들이지 않는 함수의 오류가 트리거될 수 있으므로 경고합니다.또한 값이 0 이상일 경우 스위치의 점프테이블을 쉽게 생성할 수 있습니다.
이는 Java뿐만 아니라 엄격한 타이프 체크를 가진 다른 언어에도 해당됩니다.C, C++, D, C# 등이 좋은 예입니다.
열거형은 완전히 최종적이며, 개인 생성자의 모든 값은 동일한 유형 또는 하위 유형입니다. 모든 값은 다음을 사용하여 얻을 수 있습니다.values()
, 를 취득합니다.name()
또는ordinal()
또는 숫자 또는 이름으로 열거형을 조회할 수 있습니다.
서브클래스를 정의할 수도 있습니다(개념적으로는 최종적이지만 다른 방법은 할 수 없습니다).
enum Runner implements Runnable {
HI {
public void run() {
System.out.println("Hello");
}
}, BYE {
public void run() {
System.out.println("Sayonara");
}
public String toString() {
return "good-bye";
}
}
}
class MYRunner extends Runner // won't compile.
장점 열거:
- enum은 타입 세이프이며, 스태틱필드는 그렇지 않습니다.
- 값의 수는 한정되어 있습니다(존재하지 않는 열거값을 전달할 수 없습니다).정적 클래스 필드가 있는 경우 이 오류가 발생할 수 있습니다.)
- 각 열거형에는 여러 속성(필드/getters)을 할당할 수 있습니다(캡슐화).또한 YEAR.toSeconds()와 같은 간단한 메서드도 있습니다.비교: 색상.Colors.toHex(Colors)가 있는 RED.getHex().빨강)
"예를 들어 열거 요소를 쉽게 특정 값을 할당할 수 있는 능력"
enum EnumX{
VAL_1(1),
VAL_200(200);
public final int certainValue;
private X(int certainValue){this.certainValue = certainValue;}
}
"그리고 결과적으로 충분한 노력 없이 정수를 열거형으로 변환할 수 있습니다." int 변환 메서드를 열거형으로 추가합니다.매핑을 포함한 정적 HashMap <Integer, EnumX>를 추가합니다.
ord=를 꼭 변환하고 싶은 경우VAL_200.ordinal()에서 val_200으로 돌아가기 위해서는 다음만 사용합니다.EnumX.values() [ord]
가장 큰 장점은 enum 싱글톤은 쓰기 쉽고 스레드 세이프하다는 것입니다.
public enum EasySingleton{
INSTANCE;
}
그리고.
/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
private volatile DoubleCheckedLockingSingleton INSTANCE;
private DoubleCheckedLockingSingleton(){}
public DoubleCheckedLockingSingleton getInstance(){
if(INSTANCE == null){
synchronized(DoubleCheckedLockingSingleton.class){
//double checking Singleton instance
if(INSTANCE == null){
INSTANCE = new DoubleCheckedLockingSingleton();
}
}
}
return INSTANCE;
}
}
둘 다 비슷하고 시리얼라이제이션은 실장함으로써 자체적으로 처리됩니다.
//readResolve to prevent another instance of Singleton
private Object readResolve(){
return INSTANCE;
}
또 다른 중요한 차이점은 자바 컴파일러가 다음을 처리한다는 것입니다.static final
기본 유형 필드 및 리터럴로서의 문자열 필드.이는 이러한 상수가 인라인 상태가 된다는 것을 의미합니다.와 비슷합니다.C/C++
#define
프리프로세서SO 질문을 참조하십시오.이것은 Enums의 경우는 해당되지 않는다.
Enum을 사용하면 유효한 값의 컴파일 시간을 확인할 수 있습니다.이 질문을 보세요.
Enum은 로컬일 수 있습니다.
Java 16에서는 로컬(메서드 내)에서 열거를 정의할 수 있습니다.이 범위는 열거형을 중첩 또는 개별 클래스로 정의할 수 있을 뿐만 아니라,
이 새로운 로컬 정의 범위는 새로운 레코드 기능과 함께 제공되었습니다.상세한 것에 대하여는, 「JEP 395: 레코드」를 참조해 주세요.Enum, 인터페이스 및 레코드는 모두 Java 16+에서 로컬로 정의할 수 있습니다.
그에 반해서,public static final
필드에는 항상 글로벌 범위가 있습니다.
제 생각에는enum
그럴 리가 없다final
왜냐하면 후드 컴파일러는 각각의 서브클래스를 생성하기 때문입니다.enum
엔트리를 입력합니다.
소스로부터의 상세 정보
여기에 게재되어 있는 enum에는 많은 장점이 있으며, 질문하신 대로 지금 작성 중입니다.하지만 5-6개의 필드가 있는 열거형이 있습니다.
enum Planet{
EARTH(1000000, 312312321,31232131, "some text", "", 12),
....
other planets
....
이러한 경우 enum에 여러 필드가 있는 경우 생성자와 아이볼을 확인해야 하므로 어떤 값이 어느 필드에 속하는지 이해하기 어렵습니다.
클래스static final
상수 및 사용Builder
패턴을 사용하여 이러한 개체를 만들 수 있습니다.그러나 필요한 경우 열거형을 사용하면 다른 모든 이점을 잃게 됩니다.이러한 클래스의 단점 중 하나는 다음과 같은 것을 추가해야 한다는 것입니다.Planet
에 수동으로 오브젝트list/set
의Planets.
나는 여전히 그런 클래스보다 열거형을 선호한다.values()
편리한 기능을 갖추고 있어 사용할 필요가 있는지 여부를 알 수 없습니다.switch
또는EnumSet
또는EnumMap
향후 :)
주요 이유: Enums는 컴파일 시 파라미터의 의미에 대해 명확하고 강하게 타이핑된 구조화된 코드를 작성하는 데 도움이 됩니다.다른 답변이 제시한 모든 이유 때문입니다.
Quid pro quo: Java에서는 Enum의 멤버 배열이 최종적입니다.이는 일반적으로 안전성과 테스트에 도움이 되기 때문에 좋지만, 예를 들어 라이브러리에서 기존 기본 코드를 확장하는 경우 등 경우에 따라서는 단점이 될 수 있습니다.반면 동일한 데이터가 정적 필드가 있는 클래스에 있는 경우 실행 시 해당 클래스의 새 인스턴스를 쉽게 추가할 수 있습니다(또한 해당 클래스에 대해 가지고 있는 반복 가능한 항목에 이러한 인스턴스를 추가하려면 코드를 작성해야 할 수도 있습니다).그러나 Enums의 이 동작은 변경할 수 있습니다.리플렉션을 사용하면 실행 시 새로운 멤버를 추가하거나 기존 멤버를 교체할 수 있습니다.단, 이것은 특별한 상황에서만 이루어져야 합니다.즉, 해킹 솔루션이며 예기치 않은 문제가 발생할 수 있습니다.다음에서 열거 요소를 추가 및 제거할 수 있습니까?에 대한 답변을 참조하십시오. 실행 시간(Java).
다음 작업을 수행할 수 있습니다.
public enum Size { SMALL(1), MEDIUM(2), LARGE(3) };
private int sizeValue;
Size(sizeValue) {this.sizeValue = value; }
이를 통해 SMART.getSizeValue()와 같은 크기 값을 얻을 수 있습니다.
크기를 설정하려면 Enums가 적합하지 않은 경우 상수를 정의하고 고정 값만 지정하면 됩니다.
이 링크를 체크하면 도움이 될 수 있습니다.
언급URL : https://stackoverflow.com/questions/9969690/whats-the-advantage-of-a-java-enum-versus-a-class-with-public-static-final-fiel
'sourcecode' 카테고리의 다른 글
Java에서 문자열을 UTF8 바이트 배열로 변환하는 방법 (0) | 2022.08.15 |
---|---|
Vue.js - 요소 UI - POST 요청을 트리거하지 않고 업로드 구성 요소 사용 (0) | 2022.08.15 |
Vuex 작업에 vue-resource를 사용해야 합니까? (0) | 2022.08.15 |
Vue.js 슬롯 속성 사용 방법 (0) | 2022.08.15 |
Java에서 선택된 예외와 선택되지 않은 예외 이해 (0) | 2022.08.15 |