2013-03-12 17 views
10

ben gayet iyi çalışıyor ve izinler aşağıdaki BeanValidation kodu ile açıklamalı bir fasulye doğrulamak vardır:Jenerik ve Sınıf <? Numaralandırma <?>>, class.getEnumConstants vs EnumSet.allOf (sınıfı)() uzanır

@EnumValue(enumClass = MyTestEnum.class) 
    private String field; 

    public enum MyTestEnum { 
    VAL1, VAL2; 
    } 

sadece valide olacak alan değeri "VAL1" veya "VAL2" ise.

public class EnumNameValidator implements ConstraintValidator<EnumValue, String> { 

    private Set<String> AVAILABLE_ENUM_NAMES; 

    @Override 
    public void initialize(EnumValue enumValue) { 
    Class<? extends Enum<?>> enumSelected = enumValue.enumClass(); 
    Set<? extends Enum<?>> enumInstances = Sets.newHashSet(enumSelected.getEnumConstants()); 
    AVAILABLE_ENUM_NAMES = FluentIterable 
      .from(enumInstances) 
      .transform(PrimitiveGuavaFunctions.ENUM_TO_NAME) 
      .toImmutableSet(); 
    } 

    @Override 
    public boolean isValid(String value, ConstraintValidatorContext context) { 
    if (value == null) { 
     return true; 
    } else { 
     return AVAILABLE_ENUM_NAMES.contains(value); 
    } 
    } 

} 

Neyi anlamadığım ilk denemem neden başarısız oldu. herhangi hatayı vurgulamak gelmez

Set<? extends Enum<?>> enumInstances = EnumSet.allOf(enumSelected); 

intellij 12, ama derleyici diyor: Aşağıdaki kodu yukarıdaki enumSelected.getEnumConstants() yerine kullanılması

java: method allOf in class java.util.EnumSet<E> cannot be applied to given types; 
    required: java.lang.Class<E> 
    found: java.lang.Class<capture#1 of ? extends java.lang.Enum<?>> 
    reason: inferred type does not conform to declared bound(s) 
    inferred: capture#1 of ? extends java.lang.Enum<?> 
    bound(s): java.lang.Enum<capture#1 of ? extends java.lang.Enum<?>> 

Sorunu anlamıyorum ve Ben de gayet iyi çalıştığını kod var:

private static <T extends Enum<T> & EnumAlternativeName> T safeGetByAlternativeName(Class<T> enumClass, String alternativeName) { 
    for (T t : EnumSet.allOf(enumClass)) { 
     if (t.getAlternativeName().equals(alternativeName)) { 
     return t; 
     } 
    } 
    return null; 
    } 
+0

İlgili bilet: http://stackoverflow.com/questions/5548091/problem-when-trying-to-use-generics –

+0

Bu da: http://stackoverflow.com/questions/3546745/multiple-wildcards-on- a-jenerik-m ethods-make-java-derleyici-ve-ben-çok-confu – assylias

+1

@ChristopheRoussy: Bilet? StackOverflow artık bir destek sistemidir :) – mellamokb

cevap

8

Benim tahminim olduğunu ? extends Enum<?> yılında iki ? farklı olabilir, allOf ise T extends Enum<T>'un her ikisinin de T'un aynı olmasını beklemektedir.

static enum MyEnum {} 
static class EnumValue<T extends Enum<T>> { 
    Class<T> enumClass; 
    EnumValue(Class<T> enumClass) { 
     this.enumClass = enumClass; 
    } 
    Class<T> enumClass() { return enumClass; } 
} 

Bu satırlar derlemek olacaktır:

Örneğin, şu kodu göz önünde biz enumValue.enumClass() iki T aynı olduğunu biliyorum çünkü

EnumValue<?> enumValue = new EnumValue(MyEnum.class); // raw constructor 
Set<? extends Enum<?>> enumInstances = EnumSet.allOf(enumValue.enumClass()); 

ama bu olmaz:

Bilgilerinizi kaybettiğiniz için

bir ara adım olarak bir Class<? extends Enum<?>> kullanarak.

+0

Teşekkürler, sanırım başka seçeneğim yok çünkü açıklamaların EnumValue > –

3

@ assylias çözümüne bağlı Benim açıklamam:

Ne sınıfın türü hakkında ifade etmek istiyorum bir

Class<E>, for some E, that E <: Enum<E> 

ama Java bize değişken bir tür E tanıtmak için izin olmamasıdır bir yöntem gövdesi.

Genellikle,

class G<T extends b(T)> { ... } // b(T) is a type expression that may contain T 

G<? extends A> --capture--> G<T>, for some T, that T <: A & b(T) 

değişken gizli tip tanıtmak joker ve joker yakalama yararlanabiliriz Ama Class<T> yılında T o iş yapar bir sınır olmadığı için bu, bizim durumumuzda çalışmaz.

yüzden biz o zaman başarmak için çalışıyorum hedeftir bir

Class<E>, for some E, that E <: Enum<E> 

verecek şekilde EnumClass<E>.enumClass() çağrı

class EnumClass<E extends Enum<E>> // called EnumValue in assylias's solution 

    EnumClass(Class<E> enumClass) 

    Class<E> enumClass() 

EnumClass<?> --capture--> EnumClass<E>, for some E, that E <: Enum<E> 

bağlı istenen ile yeni bir tür uygulamaya koyması gerekmektedir.

Ancak EnumClass kurucusunu nasıl arayabiliriz? Sorunun kökeni, enumClass için uygun bir türümüz yok, ancak EnumClass yapıcı doğru yazılmış bir enumClass istiyor.

Class<not-proper> enumClass = ...; 
new EnumClass<...>(enumClass); // wont work 

Neyse (?) Ham tipi jenerikler

EnumClass raw = new EnumClass(enumClass); // no generics 
EnumClass<?> wild = raw; 

yüzden istenilen tipine sınıf döküm için gerçekleştirmek için gereken asgari jimnastik

((EnumClass<?>)new EnumClass(enumClass)).enumClass() 
olup olmadığını kontrol etmenizi tipi devre dışı bırakır hangi burada yardımcı olur
+0

+1 iyi açıklamasını yapamaz. EnumClass wild = new EnumClass <> (enumClass); 'ın Java 7'de çalışıp çalışmadığını merak ediyorum. –

İlgili konular