Wady refleksji w ogóle
Odbicie jest trudniejsze do zrozumienia niż kod liniowy.
Z mojego doświadczenia wynika, że refleksja jest funkcją Java na poziomie „eksperta”. Twierdziłbym, że większość programistów nigdy nie używa aktywnie odbicia (tzn. Zużycie bibliotek korzystających z odbicia się nie liczy). Utrudnia to zrozumienie kodu dla tych programistów.
Kod odbicia jest niedostępny dla analizy statycznej
Załóżmy, że mam getFoo
klasę pobierającą i chcę zmienić jej nazwę na getBar
. Jeśli nie użyję refleksji, mogę po prostu przeszukać bazę kodu getFoo
i znajdę każde miejsce, które korzysta z gettera, abym mógł go zaktualizować, a nawet jeśli go przegapię, kompilator narzeka.
Ale jeśli miejsce, w którym używa się gettera, jest podobne callGetter("Foo")
i callGetter
działa getClass().getMethod("get"+name).invoke(this)
, to powyższa metoda go nie znajdzie, a kompilator nie będzie narzekał. Tylko wtedy, gdy kod zostanie faktycznie wykonany, otrzymasz NoSuchMethodException
. Wyobraź sobie ból, który zostanie przełknięty, jeśli ten wyjątek (który jest śledzony) zostanie połknięty, callGetter
ponieważ „jest używany tylko z zakodowanymi ciągami, tak naprawdę nie może się zdarzyć”. (Nikt by tego nie zrobił, ktoś mógłby się spierać? Tyle że OP zrobił dokładnie to samo w swojej odpowiedzi SO. Jeśli nazwa pola zostanie zmieniona, użytkownicy standardowego setera nigdy nie zauważą, z wyjątkiem wyjątkowo niejasnego błędu setera, który po cichu nic nie robi. Użytkownicy gettera mogą, jeśli mają szczęście, zauważyć wyjście konsoli zignorowanego wyjątku).
Kod odbicia nie jest sprawdzany przez kompilator
Jest to zasadniczo duży podpunkt powyższego. Chodzi o kod refleksyjny Object
. Typy są sprawdzane w czasie wykonywania. Błędy są wykrywane podczas testów jednostkowych, ale tylko w przypadku posiadania zasięgu. („To tylko getter, nie muszę go testować.”) Zasadniczo, tracisz przewagę, używając Java nad Pythonem, zyskałeś przede wszystkim.
Kod odbicia jest niedostępny do optymalizacji
Może nie w teorii, ale w praktyce nie znajdziesz JVM, która wstawia lub tworzy wbudowaną pamięć podręczną Method.invoke
. Do takich optymalizacji dostępne są normalne wywołania metod. To sprawia, że są znacznie szybsze.
Kod refleksji jest po prostu powolny
Dynamiczne wyszukiwanie metod i sprawdzanie typu niezbędne do kodu odbicia jest wolniejsze niż normalne wywołania metod. Jeśli zamienisz ten tani geter jednowierszowy w bestię odbicia, możesz (nie zmierzyłem tego) patrzeć na kilka rzędów wielkości spowolnienia.
Wadą specyficznego gettera / setera
To po prostu zły pomysł, ponieważ twoja klasa nie ma już enkapsulacji. Każde pole, które ma, jest dostępne. Równie dobrze możesz je wszystkie upublicznić.