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:
enumobjects have such methods asname()andordinal()enumobjects have specialtoString(),hashCode(),equals()andcompareTo()implementationsenumobjects are suitable forswitchoperator.
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 |