Frage

// Legacy-Code

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

// so dass ich für "Typsicherheit" generic verwenden möchten

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

// dann, hier kommt das Problem

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

// Das ist, was ich, was in meinem zu erreichen clean Telefonvorwahl:

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

}

Also, was ist der richtige Weg, dies zu tun?

War es hilfreich?

Lösung

Das ist in der Tat nicht möglich. Sie werden die „konkreten“ T irgendwie als Methode Argument übergeben müssen, so dass der tatsächliche Typ während der Laufzeit bekannt ist. Häufig verwendeter Ansatz wird es als Class<T> vorbei, so dass Sie von Class#cast() :

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

Sie können es wie folgt:

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

Andere Tipps

Karte Generika unterstützen eine Art auf alle Werte der Karte, nicht eine andere Art für bestimmte Werte. Sie können sehen, wie zu fälschen hier . Grundsätzlich ist die Idee ist, dass Sie die Art der Sicherheit auf dem Schlüssel haben müssen, wo der Schlüssel einen generischen Typen auf sie hat, das mit dem Wert einfach zu assoziieren existiert.

Am Ende des Tages werden Sie nicht in der Lage, es ohne eine unsichere Besetzung zu tun, aber man kann es auf eine Weise zu tun, dass es äußerst unwahrscheinlich macht, dass es ein Problem mit einer Besetzung ist und in eine Weise, die ist typsicher an die Benutzer Ihrer Klasse.

Eigentlich dass compiliert, auch:

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 ist irgendwie sinnlos (vielleicht, wenn Sie einen typecheck hinzufügen), aber ich fand es interessant zu wissen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top