Zanim przejrzę moją ogólną strukturę danych pod kątem indeksu wartości, chciałbym sprawdzić, czy jest to nawet wystąpienie typu, this
do którego został sparametryzowany.
Ale Eclipse narzeka, kiedy to robię:
@Override
public int indexOf(Object arg0) {
if (!(arg0 instanceof E)) {
return -1;
}
Oto komunikat o błędzie:
Nie można wykonać sprawdzenia instancji względem parametru typu E. Zamiast tego użyj jego wymazywania Obiekt, ponieważ informacje o typie ogólnym zostaną usunięte w czasie wykonywania
Jaki jest lepszy sposób na zrobienie tego?
java
generics
instanceof
typechecking
Nick Heiner
źródło
źródło
Class.isAssignableFrom
.Dwie opcje sprawdzania typu w czasie wykonywania za pomocą typów ogólnych:
Opcja 1 - Zepsuć konstruktora
Załóżmy, że nadpisujesz indexOf (...) i chcesz sprawdzić typ tylko pod kątem wydajności, aby zaoszczędzić sobie iterowania całej kolekcji.
Stwórz brudnego konstruktora, takiego jak ten:
Następnie możesz użyć isAssignableFrom, aby sprawdzić typ.
Za każdym razem, gdy tworzysz instancję obiektu, musiałbyś się powtarzać:
Możesz zdecydować, że to nie jest tego warte. W implementacji ArrayList.indexOf (...) nie sprawdzają, czy typ jest zgodny.
Opcja 2 - Niech to zawiedzie
Jeśli potrzebujesz metody abstrakcyjnej, która wymaga nieznanego typu, to wszystko, czego naprawdę chcesz, to aby kompilator przestał płakać z powodu instancji . Jeśli masz taką metodę:
Możesz go używać w ten sposób:
Rzucasz obiekt na T (twój typ ogólny), aby oszukać kompilator. Twoje rzutowanie nic nie robi w czasie wykonywania , ale nadal otrzymasz ClassCastException, gdy spróbujesz przekazać niewłaściwy typ obiektu do metody abstrakcyjnej.
UWAGA 1: Jeśli wykonujesz dodatkowe niezaznaczone rzuty w swojej metodzie abstrakcyjnej, Twoje ClassCastExceptions zostaną tutaj przechwycone. To może być dobre lub złe, więc przemyśl to.
UWAGA 2: Korzystając z instanceof . Ponieważ nie możesz go użyć, może być konieczne sprawdzenie wartości zerowej gołymi rękami.
źródło
Stary post, ale prosty sposób na wykonanie ogólnego sprawdzenia instanceOf.
źródło
Pod warunkiem, że Twoja klasa rozszerza klasę o parametr ogólny, możesz go również uzyskać w czasie wykonywania za pomocą odbicia, a następnie użyć tego do porównania, tj.
W powyższym przypadku w czasie wykonywania otrzymasz String.class z metody getParameterizedClass () i buforuje, aby nie uzyskać żadnego narzutu odbicia po wielu sprawdzeniach. Należy zauważyć, że można uzyskać inne sparametryzowane typy według indeksu z metody ParameterizedType.getActualTypeArguments ().
źródło
Miałem ten sam problem i oto moje rozwiązanie (bardzo skromne, @george: tym razem kompiluję i działam ...).
Mój problem tkwił w klasie abstrakcyjnej, która implementuje Observer. Metoda Observable fires update (...) z klasą Object, która może być dowolnym rodzajem Object.
Chcę tylko obsługiwać obiekty typu T.
Rozwiązaniem jest przekazanie klasy do konstruktora, aby móc porównywać typy w czasie wykonywania.
Do implementacji wystarczy przekazać klasę do konstruktora
źródło
Możesz też złapać nieudaną próbę rzucenia w E, np.
źródło
Technicznie nie powinieneś tego robić, o to chodzi w przypadku typów ogólnych, więc możesz sprawdzić typ kompilacji:
ale wtedy @Override może być problemem, jeśli masz hierarchię klas. W przeciwnym razie zobacz odpowiedź Yishai.
źródło
Typ środowiska wykonawczego obiektu jest względnie dowolnym warunkiem do filtrowania. Proponuję trzymać takie zabrudzenie z dala od swojej kolekcji. Osiąga się to po prostu poprzez przekazanie delegata kolekcji do filtra w konstrukcji.
źródło
Comparator
lub podobnego.)