Java enum과 private 생성자가있는 클래스의 차이점은 무엇입니까?
이 질문에 이미 답변이 있습니다.
Java enum이 실제로 어떻게 작동하는지 이해하려고했는데 생성자가 private으로 선언 된 일반 Java 클래스와 매우 유사하다는 결론에 도달했습니다.
방금이 결론에 이르렀고 많은 생각을 바탕으로 한 것이 아니지만 내가 놓친 것이 있는지 알고 싶습니다.
그래서 아래는 간단한 Java 열거 형과 동등한 Java 클래스의 구현입니다.
public enum Direction {
ENUM_UP(0, -1),
ENUM_DOWN(0, 1),
ENUM_RIGHT(1, 0),
ENUM_LEFT(-1, 0);
private int x;
private int y;
private Direction(int x, int y){
this.x = x;
this.y = y;
}
public int getEnumX(){
return x;
}
public int getEnumY(){
return y;
}
}
위와 아래 코드의 의미 차이는 무엇입니까?
public class Direction{
public static final Direction UP = new Direction(0, -1) ;
public static final Direction DOWN = new Direction(0, 1) ;
public static final Direction LEFT = new Direction(-1, 0) ;
public static final Direction RIGHT = new Direction(1, 0) ;
private int x ;
private int y ;
private Direction(int x, int y){
this.x = x ;
this.y = y ;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
차이점 :
- 열거 형은
java.lang.Enum
모든 멋진 기능을 확장 하고 얻습니다 .- 올바른 직렬화를 통한 자동 싱글 톤 동작
.toString
열거 형 이름을 복제 할 필요없이 열거 형 값에 대해 사람이 읽을 수있는 자동 방법.name
및.ordinal
특수 목적 방법- 고성능 bitset 기반
EnumSet
및EnumMap
클래스 에서 사용 가능
- 열거 형은 언어에 의해 특별히 처리됩니다.
- 열거 형은 수십 개의
public static final
필드를 작성하지 않고도 인스턴스 생성을 단순화하는 특수 구문을 사용 합니다. - 열거 형은
switch
문 에서 사용할 수 있습니다 . - 리플렉션을 사용하는 경우를 제외하고 열거 형은 열거 형 목록 외부에서 인스턴스화 할 수 없습니다.
- 열거 형은 열거 형 목록 외부로 확장 할 수 없습니다.
- 열거 형은 수십 개의
- Java는 추가 항목을 자동으로 enum으로 컴파일합니다.
public static (Enum)[] values();
public static (Enum) valueOf(java.lang.String);
private static final (Enum)[] $VALUES;
(values()
이것의 복제본을 반환)
이들 중 대부분은 적절하게 설계된 클래스로 에뮬레이션 할 수 있지만, Enum
특히 바람직한 속성 집합을 사용하여 클래스를 만들기가 정말 쉽습니다.
질문에 답하기 위해 : 기본적으로 두 접근 방식간에 차이가 없습니다. 그러나 열거 구조 같은 몇 가지 추가 지원 방법을 제공 values()
, valueOf()
클래스 -와 - 민간 생성자 접근하여 자신에 당신이 작성해야 할 것 등.
하지만 예, 저는 Java enum이 Java의 다른 클래스와 거의 똑같고 필드, 동작 등을 가질 수 있다는 점을 좋아합니다.하지만 enum을 일반 클래스와 구분하는 것은 enum이 인스턴스 / 멤버가있는 클래스 / 유형이라는 생각입니다. 미리 결정됩니다. 인스턴스 수에 제한없이 생성 할 수있는 일반적인 클래스와 달리 열거 형은 생성을 알려진 인스턴스로만 제한합니다. 예, 설명했듯이 개인 생성자를 사용하여 클래스를 사용하여이 작업을 수행 할 수도 있지만 열거 형은이를 더 직관적으로 만듭니다.
한 번 봐 가지고 이 blogpage을 , 그것은 자바 방법을 설명합니다 enum
(S)는 바이트 코드로 컴파일됩니다. 당신은 작은 추가는의 배열입니다 두 번째 코드 샘플에 비해이 있다고 볼 수 있습니다 Direction
이라고하는 객체 VALUES
. 이 배열은 열거 형에 대해 가능한 모든 값을 보유하므로 수행 할 수 없습니다.
new Direction(2, 2)
(예 : 리플렉션 사용) 그런 다음 유효한 Direction
값 으로 사용합니다 .
또한 @ Eng.Fouad가 올바르게 설명했듯이 values()
, valueOf()
및 ordinal()
.
사람들이 지적했듯이 values()
, valueOf()
그리고 ordinal()
. a Map
와 a 의 조합을 사용하여이 동작을 매우 쉽게 복제 할 수 있습니다 List
.
public class Direction {
public static final Direction UP = build("UP", 0, -1);
public static final Direction DOWN = build("DOWN", 0, 1);
public static final Direction LEFT = build("LEFT", -1, 0);
public static final Direction RIGHT = build("RIGHT", 1, 0);
private static final Map<String, Direction> VALUES_MAP = new LinkedHashMap<>();
private static final List<Direction> VALUES_LIST = new ArrayList<>();
private final int x;
private final int y;
private final String name;
public Direction(int x, int y, String name) {
this.x = x;
this.y = y;
this.name = name;
}
private static Direction build(final String name, final int x, final int y) {
final Direction direction = new Direction(x, y, name);
VALUES_MAP.put(name, direction);
VALUES_LIST.add(direction);
return direction;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public static Direction[] values() {
return VALUES_LIST.toArray(new Direction[VALUES_LIST.size()]);
}
public static Direction valueOf(final String direction) {
if (direction == null) {
throw new NullPointerException();
}
final Direction dir = VALUES_MAP.get(direction);
if (dir == null) {
throw new IllegalArgumentException();
}
return dir;
}
public int ordinal() {
return VALUES_LIST.indexOf(this);
}
@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + name.hashCode();
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Direction other = (Direction) obj;
return name.equals(other.name);
}
@Override
public String toString() {
return name;
}
}
보시다시피, 코드는 매우 빠르게 매우 투박해집니다.
I'm not sure if there is a way for replicate a switch
statement with this class; so you will lose that.
The main difference is the each enum
class implicitly extends Enum<E extends Enum<E>>
class. This leads to that:
enum
objects have such methods asname()
andordinal()
enum
objects have specialtoString()
,hashCode()
,equals()
andcompareTo()
implementationsenum
objects are suitable forswitch
operator.
All mentioned above is not applicable for your version of Direction
class. This is the "meaning" difference.
ReferenceURL : https://stackoverflow.com/questions/15734225/what-are-the-differences-between-a-java-enum-and-a-class-with-private-constructo
'Development Tip' 카테고리의 다른 글
내 jQuery : not () 선택기가 CSS에서 작동하지 않는 이유는 무엇입니까? (0) | 2020.12.25 |
---|---|
Java에서 Base64 문자열 디코딩 (0) | 2020.12.25 |
R의 히스토그램에 정규 곡선 오버레이 (0) | 2020.12.25 |
CSS : disabled pseudo-class 또는 [disabled] 속성 선택기를 사용해야합니까, 아니면 의견의 문제입니까? (0) | 2020.12.25 |
기존 가상 환경 내에서 IntellijIdea 사용 (0) | 2020.12.25 |