Domanda

Sto avendo difficoltà a capire come lanciare correttamente un oggetto generico in Java per un tipo che estende l'oggetto generico.

Ad esempio, dire che alcune operazioni di configurazione come il seguente:

public class Parameters extends SomeCustomMap<String, String>
{
   ...
}

public class SomeCustomMap<K, V> implements Map<K, V>
{
    public SomeCustomMap<K, V> getSubSet(...)
    {
        SomeCustomMap<K, V> subset;

        ...

        return subset;
    }
}

class ExampleApp
{
    private void someMethod()
    {
        Parameters params;
        Parameters paramsSubSet;

        try
        {
            ...

            paramsSubSet = (Parameters) params.getSubSet(...);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

il codice simile al precedente costantemente Esecuzione lancia un ClassCastException, del calibro di cui non capiscono fino in fondo. Qualsiasi assitence per come impostare correttamente uno scenario simile a quanto sopra sarebbe apprezzato! Vale a dire, come potrei correttamente il cast dell'oggetto del SomeCustomMap che viene restituito dalla params.getSubSet (...) il metodo di nuovo ad un oggetto parametri?

Grazie in anticipo!

È stato utile?

Soluzione

Si può provare qualcosa di simile:

public <T extends SomeCustomMap<K, V>> T getSubSet(...){
    T subset = (T)this.clone();
    subset.clear();

    return subset;
}

creazione sembra un po 'strano - sentitevi liberi di cambiarlo a quello che vuoi:)

Come bonus non sarà necessario a getto:)

paramsSubSet = params.getSubSet(...)

Altri suggerimenti

Il problema è che il sottoinsieme restituito da getSubSet è un esempio di SomeCustomMap e non di parametri.

Questo problema non si occupa di farmaci generici. Si otterrà lo stesso problema, se non è stato utilizzato farmaci generici.

Non so come si crea un'istanza di sottoinsieme ma forse si potrebbe usare il motivo template desing e di alcuni farmaci generici per risolvere il problema.

Anche se ho commentato chiedere ulteriori informazioni, in base a ciò che hai postato finora, penso che getSubSet sta costruendo un SomeCustomMap di ritorno (con new SomeCustomMap) da qualche parte. Se non si esegue l'override getSubSet in Parameters, allora Parameters.getSubset restituirà un SomeCustomMap (la classe base), non un Parameters, così il vostro typecast a Parameters fallisce.

(caldo suggerimento, se si ignora getSubSet nella classe Parameters, è possibile modificare il tipo di ritorno per Parameters ed evitare il typecast.)

I generici non intrinsecamente hanno nulla a che fare con la fusione (Save che a causa della natura di cancellazione, i parametri generici non può essere verificata nel corso di una fusione).

Se stai ricevendo un ClassCastException in questo caso, significa che l'oggetto restituito in realtà non è un'istanza di Parameters. Poco prima di lanci, provare a chiamare

System.out.println(params.getSubSet(...).getClass());

e vedere ciò che la classe in fase di esecuzione effettiva del sottoinsieme è. Le probabilità sono le bugie problema altrove, come la vostra aspettativa che il sottoinsieme è un oggetto parametri non è quasi certamente corretto in fase di esecuzione - è un SomeCustomMap o qualche altro sottoclasse di esso

.

Come altri hanno già spiegato, il problema è che l'oggetto reale si sta costruendo in getSubSet() non è un'istanza di Parameters.

Ecco una possibile soluzione. Non mi piace, ma è un modo per dichiarare il metodo in SomeCustomMap, ma ha il suo valore di ritorno essere digitato correttamente per ogni sottoclasse.

public static <T extends SomeCustomMap<K, V>> getSubSet(T fullSet)
{
    T subset;

    ... (use fullSet instead of this)

    return subset;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top