programing

Java Enum 정의

newsource 2022. 8. 3. 23:18

Java Enum 정의

자바 제네릭스를 잘 이해한다고 생각했는데, java.lang에서 다음과 같은 것을 발견했습니다.열거:

class Enum<E extends Enum<E>>

이 타입 파라미터를 해석하는 방법을 설명해 주실 수 있습니까?유사한 유형 매개변수를 사용할 수 있는 다른 예를 제공하기 위한 보너스 포인트입니다.

즉, enum의 type 인수는 enum 자체에서 같은 type 인수를 가져야 합니다.어떻게 이런 일이 일어날 수 있을까요?type 인수를 새로운 유형으로 만듭니다.따라서 Status Code라는 열거형이 있으면 다음과 같습니다.

public class StatusCode extends Enum<StatusCode>

이제 , '는 '우리'가 있어요.Enum<StatusCode> - 래 - -E=StatusCode 그럴까?EEnum<StatusCode>

를 들어 자체를 할 수 Enum API는 를 참조할 수 있는 API입니다.예를 들어 다음과 같이 말할 수 있습니다.Enum<E>를 실장하다Comparable<E>베이스 클래스는 (enum의 경우) 비교를 할 수 있지만 적절한 종류의 enum을 서로 비교만 할 수 있습니다.(EDIT: 음, 거의 - 하단의 편집 참조).

C# 포트인 Protocol Buffers에서도 비슷한 것을 사용한 적이 있습니다.에는"메시지"(불변의)과"건축업자들"(이변, 메시지를 만드는 데 이용되는). 그리고 그들은 형식 쌍으로 온다.인터페이스는 포함된다:

public interface IBuilder<TMessage, TBuilder>
  where TMessage : IMessage<TMessage, TBuilder> 
  where TBuilder : IBuilder<TMessage, TBuilder>

public interface IMessage<TMessage, TBuilder>
  where TMessage : IMessage<TMessage, TBuilder> 
  where TBuilder : IBuilder<TMessage, TBuilder>

이것은 메시지에서 하는 것과 조립을 끝낸 건설업자로부터 적절한 메시지를 전달할 수 있는 적절한 건축가(예를 들어, 좀 묻변경하는 메시지의 복사를 잡아야 할) 할 시간이 있다는 말.그 API의 사용자지만- 끔찍할 정도로 복잡해요 이런 일에 대해서 신경 쓸 그리고 그것은 where 가는 여러 반복했다 필요하지 않기 때문이죠 좋은 직업이다.

편집:이, 하지만 어떤 곳과 같지는 형식이 구현되는 것은 괜찮형식 논법을 쓰다. 이상한 형식을 만들 것을 방해하지 못하다는 점을 주목한다.목적은 올바른 경우에 그것이라기 보다 잘못된 사건으로부터 여러분을 보호한 혜택을 제공하는 것이다.

만약 '만약에'가Enum자바에서 어쨌든"특별히"이 다뤄지지 않았습니까,( 의견에서 지적했듯이):을 사용하다

public class First extends Enum<First> {}
public class Second extends Enum<First> {}

Second를 실장합니다.Comparable<First>Comparable<Second>...그렇지만First네, 이렇게 하겠습니다.

그 책 자바 Generics과 모음의 설명 다음은 수정된 버전:.우리는 가지고 있Enum

enum Season { WINTER, SPRING, SUMMER, FALL }

그것은 학급으로 확장될 것이다.

final class Season extends ...

서 ''는...Enums의 어떤 식으로든 매개 변수화된 기본 클래스가 되는 것입니다.그게 뭔지 알아봅시다.,그러면요건중하나는요.Season입니다.Comparable<Season> ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.

Season extends ... implements Comparable<Season>

에 사용할 수 있는 것은 무엇입니까?...(Parameterization)(Parameterization)로 해야 하기 Enum는 " " " 입니다Enum<Season>다음을 실현합니다.

Season extends Enum<Season>
Enum<Season> implements Comparable<Season>

★★★★★★★★★★★★★★★★★.Enum라고 하다, 라고 하는 유형으로 .Season발췌하다Season는 '이러한 파라미터'로 표시됩니다.Enum를 만족시키는 입니다.

 E extends Enum<E>

Maurice Naftalin (공저자, Java Generics and Collections)

이는 간단한 예시와 서브클래스의 연쇄 메서드 호출 구현에 사용할 수 있는 기술로 설명할 수 있습니다.setName를 반환하다Node그래서 체인이 안 통할 수 없어City:

class Node {
    String name;

    Node setName(String name) {
        this.name = name;
        return this;
    }
}

class City extends Node {
    int square;

    City setSquare(int square) {
        this.square = square;
        return this;
    }
}

public static void main(String[] args) {
    City city = new City()
        .setName("LA")
        .setSquare(100);    // won't compile, setName() returns Node
}

수 있습니다. 이 서브클래스는City이제 올바른 유형을 반환합니다.

abstract class Node<SELF extends Node<SELF>>{
    String name;

    SELF setName(String name) {
        this.name = name;
        return self();
    }

    protected abstract SELF self();
}

class City extends Node<City> {
    int square;

    City setSquare(int square) {
        this.square = square;
        return self();
    }

    @Override
    protected City self() {
        return this;
    }

    public static void main(String[] args) {
       City city = new City()
            .setName("LA")
            .setSquare(100);                 // ok!
    }
}

그것이 무엇을 의미하는지 궁금해 하는 것은 당신뿐만이 아니다.Cause Java 블로그를 참조해 주세요.

클래스가 이 클래스를 확장하면 파라미터E가 전달됩니다.매개 변수 E의 경계는 동일한 매개 변수 E"로 이 클래스를 확장하는 클래스에 대한 것입니다.

이 투고에서는, 「재귀적인 범용 타입」의 문제를 명확하게 하고 있습니다.저는 단지 이 특정한 구조가 필요한 다른 사례를 추가하고 싶었습니다.

범용 그래프에 범용 노드가 있다고 가정합니다.

public abstract class Node<T extends Node<T>>
{
    public void addNeighbor(T);

    public void addNeighbors(Collection<? extends T> nodes);

    public Collection<T> getNeighbor();
}

그런 다음 특수 유형의 그래프를 만들 수 있습니다.

public class City extends Node<City>
{
    public void addNeighbor(City){...}

    public void addNeighbors(Collection<? extends City> nodes){...}

    public Collection<City> getNeighbor(){...}
}

'마음'을 Enum츠키다

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {

    public final int compareTo(E o) {
        Enum<?> other = (Enum<?>)o;
        Enum<E> self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }

    @SuppressWarnings("unchecked")
    public final Class<E> getDeclaringClass() {
        Class<?> clazz = getClass();
        Class<?> zuper = clazz.getSuperclass();
        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
    }

    public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    } 
}

first, 엇, 는, 는, 는, 는이 죠?E extends Enum<E>평균? 즉, 유형 매개 변수는 Enum에서 확장되며 원시 유형으로 매개 변수화되지 않습니다(자체가 매개 변수화됨).

이는 열거형이 있는 경우 관련됩니다.

public enum MyEnum {
    THING1,
    THING2;
}

내가 제대로 알고 있다면, 그 번역은 번역된다.

public final class MyEnum extends Enum<MyEnum> {
    public static final MyEnum THING1 = new MyEnum();
    public static final MyEnum THING2 = new MyEnum();
}

즉, MyEnum은 다음 메서드를 수신합니다.

public final int compareTo(MyEnum o) {
    Enum<?> other = (Enum<?>)o;
    Enum<MyEnum> self = this;
    if (self.getClass() != other.getClass() && // optimization
        self.getDeclaringClass() != other.getDeclaringClass())
        throw new ClassCastException();
    return self.ordinal - other.ordinal;
}

그리고 더 중요한 건

    @SuppressWarnings("unchecked")
    public final Class<MyEnum> getDeclaringClass() {
        Class<?> clazz = getClass();
        Class<?> zuper = clazz.getSuperclass();
        return (zuper == Enum.class) ? (Class<MyEnum>)clazz : (Class<MyEnum>)zuper;
    }

하면 렇렇이 됩니다.getDeclaringClass() 곳에 Class<T>★★★★★★ 。

보다 명확한 예는 이 질문에 대해 답변한 것입니다.일반적인 경계를 지정하려면 이 구성을 피할 수 없습니다.

위키피디아에 따르면, 이 패턴은 기묘하게 반복되는 템플릿 패턴이라고 불립니다.기본적으로 CRTP 패턴을 사용함으로써 타입 캐스팅 없이 서브클래스 타입을 쉽게 참조할 수 있으며, 이는 패턴을 사용함으로써 가상 기능을 모방할 수 있다는 것을 의미합니다.

언급URL : https://stackoverflow.com/questions/211143/java-enum-definition