Question

Les deux exemples de code suivants représentent la même logique.Vérifiez si une chaîne est nulle et effectuez une branche en fonction de cette vérification.Le premier échantillon est compilé en toute sécurité.La seconde produit une erreur d’incompatibilité de type liée aux génériques Java.Ma question semble assez simple, mais elle m'échappe.Pourquoi le compilateur traite-t-il ces deux instructions différemment ?Comment puis-je mieux comprendre ce qui se passe ici ?

/* compiles cleanly */
protected Collection<String> getUserRoles(Object context,
        Set<String> mappableRoles) {
    String cookieValue = extractCookieValue(context);
    if (cookieValue != null) {
        return securityService.getRolesForUser(cookieValue);
    } else {
        return Collections.emptySet();
    }
}


/* produces a compiler error */
protected Collection<String> getUserRoles(Object context,
            Set<String> mappableRoles) {
    String cookieValue = extractCookieValue(context);
    return cookieValue == null ? Collections.emptySet()
            : securityService.getRolesForUser(cookieValue);
}

L'erreur du compilateur d'Eclipse.

Type mismatch: cannot convert from Set<capture#1-of ? extends Object> to Collection<String>

Comme demandé, voici la partie pertinente de l'interface SecurityService.

public interface SecurityService {
    public Set<String> getRolesForUser(String userId);
}
Était-ce utile?

La solution

Le problème devrait résider dans la manière dont le compilateur interprète la valeur de retour de l'opérateur ternaire.Vous voudrez peut-être jeter un oeil à partie 15.25 du JLS ou à ceci question (un peu lié car c'est encore plus compliqué par l'autoboxing et cela génère une erreur au moment de l'exécution plutôt qu'au moment de la compilation).

J'espère que cela vous met sur la bonne direction.

Autres conseils

C'est parce que Collections.emptySet() renvoie un non typé Set.Essayez plutôt ceci :

Collections.<String>emptySet()

Collections.emptySet() est déclaré comme

public static final <T> Set<T> emptySet()

La première T est utilisé pour Inférence de type.La deuxième getUserRoles l'implémentation est trop complexe pour que le compilateur Java puisse détecter le bon type.C'est la raison du problème.Solution de contournement:

protected Collection<String> getUserRoles(Object context,
            Set<String> mappableRoles) {
    String cookieValue = extractCookieValue(context);
    Collection<String> a = null;
    return cookieValue == null ? a = Collections.emptySet()
            : securityService.getRolesForUser(cookieValue);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top