2014-12-31 11 views
5

다음 코드 컴파일 (예상대로 테스트를 실행합니다) 이클립스 :불일치 - 열거 형, 인터페이스 및 제네릭

import java.util.EnumSet; 
public class EnumTest { 

    static enum Cloneables implements Cloneable { 
     One, Two, Three; 
    } 

    public <T extends Cloneable> T getOne(Class enumType) { 
     EnumSet<? extends T> set = EnumSet.allOf(enumType); 
     return set.iterator().next(); 
    } 
} 

을하지만, javac (JDK 7) 중 하나를 사용하여 컴파일 직접 또는 통해 Maven은 다음과 같은 오류와 함께 실패합니다

type argument ? extends T is not within bounds of type-variable E 

는 솔직히 말해서, 열거의 복잡성 + 내가 코드를 작성했지만, 내가 생각 모든 놀이 형식 매개 변수 (제네릭)이 한 번 저를 던졌다 + 인터페이스 마침내 그것을 맞았다.

목표는 다음과 같이 호출하는 코드를 작성하는 것입니다 : 예를 들어

Cloneable something = enumTest.getOne(Cloneables.class); 

, 이클립스에서 다음 테스트를 컴파일하고 전달합니다

@Test 
public void testGetFirst() { 
    assertSame(Cloneables.One, getOne(Cloneables.class)); 
} 

인에 대한 모든 단서 "올바른"를 Eclipse를 또는 javac에 감사드립니다. EnumSet.allOf()에 사용하고 또한 방법에 의해, EnumSet

에서 열거 객체의 유형을 결정 할 수있는 방법 PARAM로 수업을 : 또한 감사

아이디어를 구현하는 다른 방법에 대한 조언을 ,이 방법의 목적을 비판하지 마라. 나는 더 유용하고 의미있는 코드에서 그것을 줄였습니다. 나는 "열거 형에서 첫 번째 요소를 찾는 것"의 장점에 대해 토론하는 것에는 관심이 없습니다. -이 질문의 핵심은 아닙니다. 당신은 또한

public <T extends Enum<T> & Cloneable> T getOne(Class enumType) 

, 당신은 당신의 EnumSet에 와일드 카드를 필요로하지 않으며, :

+0

이것은 javac (JDK 1.7.0_60)의 버그 일 수 있습니다. 아래에서 허용되는 대답은 해결 방법입니다 (실제로는 더 깨끗한 코드). 자세한 분석을 보려면 https://bugs.eclipse.org/bugs/show_bug.cgi?id=456459#c7 –

답변

4

당신은 T이 열거 형, 또는이 EnumSet의 제약 조건을 충족하지 않도록해야

public <T extends Enum<T> & Cloneable> T getOne(Class<T> enumType) { 
    EnumSet<T> set = EnumSet.allOf(enumType); 
    return set.iterator().next(); 
} 
+1

그런 식의 매개 변수를 선언 할 때 '&'연산자를 적용 할 수 있다는 것을 알지 못했습니다. Java 코드를 작성하는 데 거의 18 년이 걸렸지 만, 오늘 새로운 것을 배웠습니다! –

+0

그건 그렇고, 내가'클래스 '의 원시 형식을 사용했던 이유는'T'가'Enum'을 확장하지 않으면 Eclipse 컴파일러는'Class' 유형 매개 변수에 대한 어떤 값도 허용하지 않기 때문입니다. 그래서 raw를 사용하는 것은'Cloneable'과'Enum'을'T'에 결합하는 것을 모르는 부작용이었습니다. –

+0

흥미롭게도 이클립스는'EnumSet '으로 세트를 선언 할 수 없습니다. * "바인딩 불일치 : 유형 T는 EnumSet 유형이 >" *. 다행히도,'EnumSet