Odbicie to potężna konstrukcja, która jest często używana przez podstawowe biblioteki, takie jak Guice i Hibernate, aby ułatwić życie. Jest często używany tam, gdzie klasa musi być skonfigurowana, a następnie utworzona w locie. Na przykład:
public Strategy prepare(String clazz, Properties config) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> clazz = Class.forName(clazz);
Strategy strategy = (Strategy) clazz.newInstance();
strategy.initialise(config);
return strategy;
}
W tym miejscu parametr clazz określa klasę do utworzenia instancji. Zakłada się, że klasa będzie podklasą klasy/interfejsu Strategii. Jest on następnie inicjowany z ustawieniami przekazywanymi za pośrednictwem parametru konfiguracyjnego. Pozwala to na wysoce konfigurowalne/dynamiczne środowisko.
Jednak odbicie często prowadzi do bardzo niebezpiecznego (i złośliwego) kodu, dlatego należy unikać refleksji, chyba że jest to absolutnie konieczne. Pamiętaj też, że odbicie jest wolniejsze niż bezpośrednie połączenie. Oto rzeczywisty przykład wyciągnięty z systemu produkcyjnego, jak NIE używać odbicia.
private static CacheManager getRawInstance() {
lock.lock();
try {
final Field field = CacheManager.class.getDeclaredField("singleton");
field.setAccessible(true); // << -- ??
return (CacheManager) field.get(CacheManager.class);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
} finally {
lock.unlock();
}
}
Tutaj pole prywatne w ehcache jest zmieniane i dostępne. To jest naprawdę złe kodowanie.
Albo http://stackoverflow.com/questions/9222621/java-what-scenarios-call-for-the-use-of-reflection –