Domanda

Diciamo che ho la seguente classe:

public class Test<E> {
    public boolean sameClassAs(Object o) {
        // TODO help!
    }
}

Come potrei verificarlo? o è la stessa classe di E?

Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;

Non riesco a modificare la firma del metodo da (Object o) poiché sto sovrascrivendo una superclasse e quindi non posso scegliere la firma del mio metodo.

Preferirei inoltre non tentare un cast e quindi rilevare l'eccezione risultante se fallisce.

È stato utile?

Soluzione

Un'istanza di Test non ha informazioni su cosa E è in fase di esecuzione.Quindi, devi superare a Class<E> al costruttore di Test.

public class Test<E> {
    private final Class<E> clazz;
    public Test(Class<E> clazz) {
        if (clazz == null) {
            throw new NullPointerException();
        }
        this.clazz = clazz;
    }
    // To make things easier on clients:
    public static <T> Test<T> create(Class<T> clazz) {
        return new Test<T>(clazz);
    }
    public boolean sameClassAs(Object o) {
        return o != null && o.getClass() == clazz;
    }
}

Se vuoi una relazione "istanza di", usa Class.isAssignableFrom invece del Class confronto.Nota, E dovrà essere un tipo non generico, per lo stesso motivo Test ha bisogno del Class oggetto.

Per esempi nell'API Java, vedere java.util.Collections.checkedSet e simili.

Altri suggerimenti

Il metodo che ho sempre utilizzato è riportato di seguito.È doloroso e un po' brutto, ma non ne ho trovato uno migliore.È necessario passare il tipo di classe durante la costruzione, poiché quando i generici vengono compilati, le informazioni sulla classe vengono perse.

public class Test<E> {
    private Class<E> clazz;
    public Test(Class<E> clazz) {
       this.clazz = clazz;
    }
    public boolean sameClassAs(Object o) {
        return this.clazz.isInstance(o);
    }
}

Potrei solo farlo funzionare in questo modo:

public class Test<E> {  

    private E e;  

    public void setE(E e) {  
        this.e = e;  
    }

    public boolean sameClassAs(Object o) {  

        return (o.getClass().equals(e.getClass()));  
    }

    public boolean sameClassAs2(Object o) {  
        return e.getClass().isInstance(o);  
    }
}

Stavo solo cercando di fare la stessa cosa, e un bel trucco che ho appena realizzato è che puoi provare un cast e, se il cast fallisce, verrà lanciata ClassCastException.Puoi prenderlo e fare qualunque cosa.

quindi il tuo metodo sameClassAs dovrebbe assomigliare a:

public boolean sameClassAs(Object o) {
    boolean same = false;
    try {
        E t = (E)o;
        same = true;
    } catch (ClassCastException e) {
        // same is false, nothing else to do
    } finally {
        return same;
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top