Due opzioni per tipo di runtime verifica con i generici:
Opzione 1 - Corrupt tuo costruttore
Supponiamo modo si sostituisce indexOf (...), e si desidera controlla il tipo solo per le prestazioni, per salvarti ripetendo l'intera collezione.
Fai un costruttore di sporco come questo:
public MyCollection<T>(Class<T> t) {
this.t = t;
}
quindi è possibile utilizzare isAssignableFrom per verificare il tipo.
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
//...
Ogni volta che si istanziare l'oggetto che avrebbe dovuto ripetersi:
new MyCollection<Apples>(Apples.class);
Si potrebbe decidere che non vale la pena. Nell'implementazione di ArrayList.indexOf(...), non controllano che il tipo corrisponda.
Opzione 2 - Lasciare fallire
Se è necessario utilizzare un metodo astratto che richiede la vostra tipo sconosciuto, quindi tutto quello che vuole veramente è per il compilatore a smettere di piangere su instanceof. Se si dispone di un metodo come questo:
protected abstract void abstractMethod(T element);
è possibile utilizzarlo in questo modo:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
//...
si sta casting l'oggetto da T (il vostro tipo generico), giusto per ingannare il compilatore. Your cast does nothing at runtime, ma si otterrà comunque un ClassCastException quando si tenta di passare il tipo di oggetto errato nel metodo astratto.
NOTA 1: se si sta facendo ulteriori calchi incontrollati nel metodo astratto, i tuoi ClassCastExceptions saranno catturati qui. Potrebbe essere buono o cattivo, quindi pensaci.
NOTA 2: You get a free null check when you use instanceof. Dal momento che non è possibile utilizzarlo, potrebbe essere necessario verificare la presenza di null a mani nude.
Non penso che tu voglia 'Class.isAssignableFrom'. –
@ Tom, l'ho scritto ieri sera dalla memoria, e l'ho corretto per passare effettivamente la classe (duh!) Ma per il resto non capisco perché non lo vorreste (forse ho bisogno di più caffè stamattina, sono solo sulla mia prima tazza). – Yishai
Sono con Tom. Potresti chiarirlo? Usare isAssignableFrom() sarebbe stata la mia scelta per il lavoro. Forse mi manca qualcosa? –