Prestaties van reflection en alternatieven
Benchmark de overhead van reflection ten opzichte van directe aanroepen en onderzoek MethodHandles als sneller alternatief.
Prestaties van reflection en alternatieven is een gratis Java Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.
Extra kosten van reflectie
Reflectieve aanroepen zijn aanzienlijk langzamer dan directe aanroepen: bij het opzoeken van een methode worden maps doorlopen, beveiligingscontroles uitgevoerd en waarden ingepakt. Na het opwarmen van de JIT is invoke ongeveer 10–50 keer langzamer dan een directe aanroep.
Prestaties van reflectie meten
Gebruik JMH (Java Microbenchmark Harness) om de extra kosten van reflectie te vergelijken met die van directe aanroepen. Meet altijd in de juiste context — de JIT kan een deel van de extra kosten optimaliseren.
@Benchmark
public String directCall() { return user.getName(); }
@Benchmark
public String reflectiveCall() throws Exception {
return (String) NAME_METHOD.invoke(user); // NAME_METHOD cached
}Field- en Method-objecten cachen
Het opzoeken van een methode of veld (getDeclaredMethod) is het duurste onderdeel. Cache het resultaat in een static final-veld; invoke op een gecachet object is veel sneller.
public class UserAccessor {
private static final Method GET_NAME;
static {
try {
GET_NAME = User.class.getDeclaredMethod("getName");
GET_NAME.setAccessible(true);
} catch (NoSuchMethodException e) { throw new ExceptionInInitializerError(e); }
}
public static String getName(User u) throws Exception { return (String) GET_NAME.invoke(u); }
}MethodHandles: bijna de snelheid van directe aanroepen
MethodHandles.lookup().findVirtual() maakt een handle die de JIT na enkele aanroepen kan optimaliseren tot bijna de snelheid van een directe aanroep. Dit heeft de voorkeur voor veelgebruikte reflectiecode.
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(User.class, "getName",
MethodType.methodType(String.class));
// Cast to functional interface for max speed:
Function<User, String> getName = user -> {
try { return (String) mh.invokeExact(user); }
catch (Throwable t) { throw new RuntimeException(t); }
};LambdaMetafactory: maximale prestaties
LambdaMetafactory maakt tijdens uitvoering een lambda op basis van een MethodHandle, waardoor na JIT-optimalisatie de snelheid van een directe aanroep wordt bereikt. Jackson en Kryo gebruiken dit intern.
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(User.class, "getName",
MethodType.methodType(String.class));
CallSite site = LambdaMetafactory.metafactory(lookup, "get",
MethodType.methodType(Function.class),
MethodType.methodType(Object.class, Object.class),
mh, MethodType.methodType(String.class, User.class));
Function<User, String> fn = (Function<User, String>) site.getTarget().invokeExact();
System.out.println(fn.apply(user));Codegeneratie tijdens compileren met APT
Annotatieverwerkers genereren bronbestanden tijdens het compileren. Frameworks zoals Lombok en MapStruct gebruiken APT om typeveilige standaardcode zonder reflectie te produceren — voor maximale prestaties tijdens uitvoering.
Byte Buddy voor codegeneratie tijdens uitvoering
Byte Buddy genereert tijdens uitvoering subklassen en proxy's met behulp van bytecode-manipulatie. Het is veel sneller dan dynamische proxy's voor veelgebruikte paden en wordt gebruikt door Mockito, Hibernate en ByteCodeLib.
// Byte Buddy example — create a class with a method:
Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello Byte Buddy!"))
.make()
.load(getClass().getClassLoader())
.getLoaded();
System.out.println(dynamicType.newInstance()); // Hello Byte Buddy!Reflectie op veelgebruikte paden vermijden
Gebruik reflectie voor de initialisatie van frameworks, dus tijdens het opstarten, en niet voor paden die per aanvraag worden uitgevoerd. Verplaats reflectief werk naar het opstarten van de toepassing en cache alles zo veel mogelijk.
Modulesysteem en reflectie (Java 9 en hoger)
Modules in Java 9 en hoger blokkeren diepe reflectie standaard. Verleen toegang met --add-opens of module-info.java opens-richtlijnen. Bibliotheken gebruiken steeds vaker MethodHandles om --add-opens overbodig te maken.
// module-info.java:
module com.example.app {
opens com.example.model to com.example.framework; // allow reflective access
}Afweging tussen reflectie en codegeneratie
Reflectie: eenvoudig, flexibel, langzaam. Codegeneratie (APT/Byte Buddy): snel, typeveilig, complex om in te stellen. Kies op basis van het moment waarop het doel wordt gebruikt: tijdens het opstarten is reflectie prima, maar tijdens de verwerking van aanvragen kun je reflectie beter vermijden.
Reflectiegebruik profileren
Gebruik JFR (Java Flight Recorder) of async-profiler om te vinden waar de extra kosten van reflectie zich opstapelen. Zoek naar sun.reflect.* of java.lang.reflect.* in de lijst met veelgebruikte methoden.
Korte controle
Wat is tijdens uitvoering het snelste alternatief voor Method.invoke bij veelgebruikte reflectie-aanroepen?
Samenvatting
Cache Method- en Field-objecten om de kosten van opzoeken te verlagen. Gebruik MethodHandles voor veelgebruikte paden. Gebruik LambdaMetafactory voor maximale snelheid. Gebruik APT of Byte Buddy om reflectie in kritieke delen volledig te vermijden.
Leer Java met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 104
- Lessen
- 374
Veelgestelde vragen
Is de les “Prestaties van reflection en alternatieven” gratis?
Ja — de volledige tekst van “Prestaties van reflection en alternatieven” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.
Wat leer ik in “Prestaties van reflection en alternatieven”?
Benchmark de overhead van reflection ten opzichte van directe aanroepen en onderzoek MethodHandles als sneller alternatief. Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Java Academy te beginnen?
Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “Prestaties van reflection en alternatieven”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Java Academy?
Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Klassen inspecteren met reflection
- Methoden aanroepen en velden benaderen
- Dynamische proxies met InvocationHandler
- Prestaties van reflection en alternatieven