Pregunta

// código heredado

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

// así que quiero utilizar genérico de "seguridad de tipo"

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

// luego, aquí viene el problema

<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?
}

// Esto es lo que lo lograr en mi limpia código de llamada:

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

}

Así que, ¿cuál es la forma correcta de hacer esto?

¿Fue útil?

Solución

Eso no es realmente posible. Tendrá que pasar el T "concreto" de alguna manera como argumento de un método para que el tipo real es conocido en tiempo de ejecución. enfoque utilizado es el de pasarlo como Class<T>, por lo que se puede hacer uso de Class#cast() :

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

Se puede usar de la siguiente manera:

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

Otros consejos

Mapa genéricos soportan un tipo en todos los valores del mapa, no un tipo diferente para valores específicos. Se puede ver cómo fingir aquí . Básicamente, la idea es que tiene que tener la seguridad de tipos en la llave, donde la clave tiene un tipo genérico en el mismo que existe simplemente para asociarse con el valor.

Al final del día usted no será capaz de hacerlo sin un reparto insegura, pero se puede hacer de una manera que hace que sea muy poco probable que exista un problema con un reparto y de una manera que es typesafe a los usuarios de su clase.

En realidad que recopila, también:

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");
    }
}

Es una especie de sentido (tal vez si se agrega una typecheck) pero me pareció interesante saber.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top