Question

// code existant

void setCacheValue(String name, Object value){
    getServletContext().setAttribute(name, value);
}
Object getCacheValue(String name){
    return getServletContext().getAttribute(name);
}

// donc je veux utiliser générique pour "la sécurité de type"

// first, set method seems working perfectly
<T> void setCacheObject(String name, T value){
    getServletContext().setAttribute(name, value);
}

// vient donc ici le problème

<T> T getCacheValue(String name){    
    // of course, I cannot change servlet class - it returns Object type
    Object value = getServletContext().getAttribute(name);
    // would this work:     
    return  (T) value;
    // this cast is meaningless... but how should I do it?
}

// Voici ce que je quoi réaliser dans mon clean code d'appel:

{
    double x = 1.2;
    setCacheValue("x", x);
    //...
    // later
    Double value = getCacheValue("x");
    // too bad cannot use primitive type - it cannot handle null

}

Alors, quelle est la bonne façon de le faire?

Était-ce utile?

La solution

C'est en effet pas possible. Vous aurez besoin de passer le T « concret » en quelque sorte comme argument de la méthode de sorte que le type réel est connu lors de l'exécution. approche couramment utilisée passe comme Class<T>, de sorte que vous pouvez utiliser Class#cast() :

<T> T getCacheValue(String name, Class<T> type) {
    return type.cast(getServletContext().getAttribute(name));
}

Vous pouvez l'utiliser comme suit:

Double value = getCacheValue("x", Double.class);

Autres conseils

génériques prennent en charge un type Carte sur toutes les valeurs de la carte, et non pas un autre type de valeurs spécifiques. Vous pouvez voir comment truquer ici . Fondamentalement, l'idée est que vous devez avoir la sécurité de type sur la clé, où la clé a un type générique sur ce qui existe simplement associer à la valeur.

A la fin de la journée, vous ne serez pas en mesure de le faire sans un casting dangereux, mais vous pouvez le faire d'une manière qui le rend extrêmement improbable qu'il y ait un problème avec un casting et d'une manière qui est typesafe aux utilisateurs de votre classe.

En fait compilant, aussi:

public class Test
{
    <T> T getCacheValue(String name){    
        // of course, I cannot change servlet class - it returns Object type
        Object value = getServletContext().getAttribute(name);
        // would this work:     
        return  (T) value;
        // this cast is meaningless... but how should I do it?
    }

    public static void main(String... args)
    {
        Test t = new Test();
        Double double = t.<Double>getCacheValue("Double");
    }
}

Il est un peu vain (peut-être si vous ajoutez un typecheck) mais je l'ai trouvé intéressant de savoir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top