Widzę wzrost wydajności podczas używania getClass()
i ==
operatora nad instanceOf
operatorem.
Object str = new Integer("2000");
long starttime = System.nanoTime();
if(str instanceof String) {
System.out.println("its string");
} else {
if (str instanceof Integer) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
starttime = System.nanoTime();
if(str.getClass() == String.class) {
System.out.println("its string in equals");
} else {
if(str.getClass() == Integer.class) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
Czy istnieją jakieś wytyczne, który z nich korzystać getClass()
lub instanceOf
?
Biorąc pod uwagę scenariusz: Wiem dokładnie dopasowane do klas, to znaczy String
, Integer
(są to zajęcia końcowe), etc.
Czy używanie instanceOf
operatora jest złą praktyką?
java
class
instanceof
kropelka
źródło
źródło
Odpowiedzi:
Powodem, dla którego wydajność
instanceof
igetClass() == ...
jest inna, jest to, że robią różne rzeczy.instanceof
sprawdza, czy odwołanie do obiektu po lewej stronie (LHS) jest wystąpieniem typu po prawej stronie (RHS), czy jakimś podtypem .getClass() == ...
sprawdza, czy typy są identyczne.Dlatego zalecamy zignorowanie problemu z wydajnością i skorzystanie z alternatywy, która daje odpowiedź, której potrzebujesz.
Niekoniecznie. Nadużywanie któregokolwiek z nich
instanceOf
lubgetClass()
może oznaczać „zapach projektu”. Jeśli nie będziesz ostrożny, otrzymasz projekt, w którym dodanie nowych podklas powoduje znaczną ilość przeróbek kodu. W większości sytuacji preferowanym podejściem jest użycie polimorfizmu.Jednak są przypadki, w których NIE są to „zapachy projektu”. Na przykład,
equals(Object)
musisz przetestować rzeczywisty typ argumentu i zwrócić,false
jeśli nie pasuje. Najlepiej to zrobić za pomocągetClass()
.Pojęcia takie jak „najlepsza praktyka”, „zła praktyka”, „zapach projektu”, „anty-wzór” itd. Powinny być używane oszczędnie i traktowane z podejrzliwością. Zachęcają do czarno-białego myślenia. Lepiej jest wydawać sądy w kontekście, niż opierać się wyłącznie na dogmacie; np. coś, co ktoś powiedział, jest „najlepszą praktyką”.
źródło
code smell
to użycie albo. Oznacza to, że jest to konsekwencja złego projektu (niepolimorficznego) kodu, który zmusza cię do użycia. czy mogę w ten sposób wywnioskować użycie któregokolwiek z nich?instanceof
&getClass()
pojawia się z powodu istniejącego złego projektu (niepolimorficznego) kodu. mam rację?instanceof
(na przykład) jest złym projektem. Są sytuacje, w których może to być najlepsze rozwiązanie. To samo dotyczygetClass()
. Powtórzę, że powiedziałem „nadużywać”, a nie „używać” . Każdy przypadek należy oceniać merytorycznie ... a nie ślepo stosując jakąś nieuzasadnioną dogmatyczną zasadę.Czy chcesz dokładnie dopasować klasę , np. Tylko dopasowywanie
FileInputStream
zamiast dowolnej podklasyFileInputStream
? Jeśli tak, użyjgetClass()
i==
. Zazwyczaj robiłbym to w anequals
, więc wystąpienie X nie jest uważane za równe wystąpieniu podklasy X - w przeciwnym razie możesz dostać się do trudnych problemów z symetrią. Z drugiej strony jest to bardziej przydatne do porównywania, że dwa obiekty należą do tej samej klasy niż jednej określonej klasy.W przeciwnym razie użyj
instanceof
. Zauważ,getClass()
że będziesz musiał upewnić się, że masz niezerowe odniesienie, od którego zaczniesz, w przeciwnym razie otrzymasz aNullPointerException
, podczas gdyinstanceof
zwróci po prostu,false
jeśli pierwszy operand ma wartość null.Osobiście powiedziałbym, że
instanceof
jest bardziej idiomatyczny - ale intensywne używanie któregokolwiek z nich jest w większości przypadków zapachem projektowym.źródło
Wiem, że minęło trochę czasu, odkąd o to zapytano, ale wczoraj nauczyłem się alternatywy
Wszyscy wiemy, że możesz:
ale co, jeśli nie wiesz dokładnie, jaki to rodzaj zajęć? nie możesz generalnie zrobić:
ponieważ daje błąd kompilacji.
Zamiast tego tutaj jest alternatywa - isAssignableFrom ()
Na przykład:
źródło
isAssignableFrom
. Prawidłowy sposób pisaniao instanceof String
za pomocą refleksji toString.getClass().isInstance(o)
. Tak mówi javadoc: ta metoda jest dynamicznym odpowiednikieminstanceof
operatora języka Java .getClass () ma ograniczenie, że obiekty są równe tylko innym obiektom tej samej klasy, tego samego typu w czasie wykonywania, jak pokazano na wyjściu poniższego kodu:
Wyjścia:
SubClass rozszerza ParentClass. subClassInstance jest instancją ParentClass.
Różne wyniki funkcji getClass () zwracają z subClassInstance i parentClassInstance.
źródło