2009-09-22 12 views
1

J'ai une affaire assez simple où je fais une mission générique de base:comment lancer du CRT en java?

final Detail detail = field.getAnnotation(Detail.class); 
final String example = detail.example(); 
final Class<?> type = field.getType(); 
if (List.class.isAssignableFrom(type)) 
        ... 
else if (Enum.class.isAssignableFrom(type)) 
    setValue(contract, field, Enum.valueOf(type, example)); 
else if (...) 
..... 

mais le Enum.valueOf() est un peu difficile à appeler, dans mon cas, l'erreur est la suivante:

valueOf (java .lang.Class, java.lang.String) ne peut en java.lang.Enum appliquer à (java.lang.Class, java.lang.String)

Cela rend parfaitement logique puisque le type est Class<Object>. Mais puisque Enum est CRTP, je ne peux pas trouver un bon moyen de lancer le type pour rendre le compilateur heureux. Est-ce que l'utilisation du type brut Enum.valueOf((Class)type, example)) la seule réponse? Il me donne 2 avertissements au lieu d'un seul.

+0

Quelqu'un a modifié la question 6 ans plus tard? faim de karma ne sommes-nous pas? – nraynaud

Répondre

2

La ligne suivante fera avec un seul avertissement:

... 
setValue(contract, field, Enum.valueOf(type.asSubclass(Enum.class), example)); 
... 
+0

J'achète vos affaires, merci. – nraynaud

1

Vous pouvez écrire une méthode d'aide pour capturer un type « T » qui satisfait l'exigence de Enum:

private <T extends Enum<T>> T helper(Class<?> type, String example) { 
    return Enum.valueOf((Class<T>)type, example); 
} 

cela ne devrait avoir un avertissement

et vous pouvez l'utiliser comme

else if (Enum.class.isAssignableFrom(type)) 
    setValue(contract, field, helper(type, example)); 

Edit: D'accord, alors que diriez-vous:

private <T extends Enum<T>> Object helper(Class<?> type, String example) { 
    return Enum.valueOf((Class<T>)type, example); 
} 
+0

Je reçois toujours le même message d'erreur, sur le nouvel assistant. C'est logique, le même problème est transposé au type de retour d'aide maintenant. setValue() prend un objet en tant que paramètre. pour simplifier le cas, final Valeur de l'objet = quelque chose (type, exemple); devrait marcher. Et pour l'instant je ne peux que faire "quelque chose" avec 2 avertissements et en utilisant des types bruts. – nraynaud

+0

désolé, mais votre édition n'a aucune chance de travailler, le T est lié nulle part dans le prototype, aucune inférence ne peut avoir lieu. – nraynaud

1

Je ne pense pas qu'il est possible de supprimer les avertissements du compilateur

Le meilleur scénario est de réduire toutes les erreurs dans un comme @tangens fait.

Trouvé deux fils de discussion qui montrent des réponses infructueuses et explique le pourquoi un peu plus.

Je mis en place un exemple complet pour démontrer la question que je le vois.

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import java.lang.reflect.Field; 
import java.util.List; 

public class Test { 
    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.FIELD) 
    public @interface Detail { 
    String example(); 
    } 

    public enum ExampleEnum { 
    FOO_BAR, HELLO_WORLD 
    } 

    @Detail(example = "FOO_BAR") 
    public ExampleEnum test; 

    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { 
    populate(new Test()); 
    } 

    public static void populate(Object o) throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException { 
    final Field field = o.getClass().getField("test"); 
    final Detail detail = field.getAnnotation(Detail.class); 
    System.out.println("Annotation = " + detail); 
    final String example = detail.example(); 
    final Class<?> type = field.getType(); 
    System.out.println("Field Class = " + type.getName()); 
    if (List.class.isAssignableFrom(type)) { 
    } else if (Enum.class.isAssignableFrom(type)) { 
     Class<? extends Enum> enumType = type.asSubclass(Enum.class); // Enum is a raw type. References to generic type Enum<E> should be parameterized 
     Enum val = Enum.valueOf(enumType, example); // 1) Enum is a raw type. References to generic type Enum<E> should be parameterized 
                // 2) Type safety: Unchecked invocation valueOf(Class<capture#7-of ? extends Enum>, String) of the generic 
                // method valueOf(Class<T>, String) of type Enum 
     field.set(o, val); 
    } 
    } 
} 
+0

Article drôle sur Enum. http://weblogs.java.net/blog/arnold/archive/2005/06/generics_consid_1.html – TJR

Questions connexes