sourcecode

Java 열거형과 공개 정적 최종 필드가 있는 클래스의 장점은 무엇입니까?

copyscript 2022. 8. 15. 21:31
반응형

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);

내가 말할 수 있는 한, 카사블랑카의 대답은 이것을 만족시키는 유일한 것이다.

  1. 안전 유형을 지정하고 안전을 중시하십시오.
  2. 보증 싱글톤.
  3. 메서드를 정의 및 재정의할 수 있습니다.
  4. 의 할 수 .switch 「」case조건 없는 진술
  5. 「」를한 값의 삽입 시퀀셜라이제이션에 값:ordinal().
  6. 값이 아닌 이름에 의한 시리얼라이제이션으로 장래에 대비할 수 있습니다.
  7. 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는 역호환성을 유지해야 하기 때문에 항상 이 애매모호함에 시달리게 됩니다.

은 단지 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.enumpublic 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 스테이트먼트에서 가능한 모든 열거값을 처리하지 않는다고 경고할 수 있습니다(즉, 다음과 같은 경우).defaultn개의 열거값 중 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.

장점 열거:

  1. enum은 타입 세이프이며, 스태틱필드는 그렇지 않습니다.
  2. 값의 수는 한정되어 있습니다(존재하지 않는 열거값을 전달할 수 없습니다).정적 클래스 필드가 있는 경우 이 오류가 발생할 수 있습니다.)
  3. 각 열거형에는 여러 속성(필드/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/setPlanets.

나는 여전히 그런 클래스보다 열거형을 선호한다.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

반응형