Skip to content
Ameen Abozaid
MID-009

Advanced generics and reflection

  • 6 Lessons
  • 2.5 h practice (estimate)
On this page 8 topics

Overview

Topics

  • Type erasure
  • reflection
  • annotations
  • dynamic proxies

Learn first

2.5 h of practice (estimate)

Learning outcomes

  1. Explain type erasure and its consequences (no new T(), bridge methods, heap pollution).
  2. Apply PECS to wildcard signatures.
  3. Inspect classes, methods, and annotations with reflection and write a custom annotation processed at runtime.
  4. Explain how Spring uses reflection and dynamic proxies (and why @Transactional self-invocation fails).

Lessons

  1. 01Type erasure
  2. 02Wildcards and PECS
  3. 03Reflection
  4. 04Custom annotations
  5. 05Dynamic proxies
  6. 06Demo: building a mini @Timed with a proxy

Lab and exercises

Lab

MID-009-LAB1 · Audit annotation

Outcomes: 3–4 (with 1–2 in exercises) · Time: ~2.5 h Create an @Audited annotation and a proxy-based interceptor that logs calls to annotated methods (method name, arguments, duration). Apply it to a Shop service interface. Demonstrate the self-invocation limitation. Acceptance: works through an interface; self-invocation limitation demonstrated.

Exercises (assessment: exercises plus a proxy-behavior quiz)

IDOutcomeTask
MID-009-EX011Show that new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass(); explain, then use a raw list to cause heap pollution and observe where the exception appears.
MID-009-EX021Write <T> T create(Class<T>) as the replacement for new T().
MID-009-EX032Write addAll(Collection<? extends T> src, Collection<? super T> dst); explain PECS with Integer, Number, Object.
MID-009-EX043Use reflection to list all methods annotated with a custom @Audited on a class.
MID-009-EX054Explain why @Transactional on b() does not work when called from a() in the same class, and give two fixes.
MID-009-EX063Time 1,000,000 direct vs reflective calls; report the difference and one way to reduce it.
Show solutions
  • EX01 Both classes are ArrayList (erased). Adding an Integer through a raw reference compiles with a warning; ClassCastException appears later when a String is read.
  • EX02 return type.getDeclaredConstructor().newInstance();
  • EX03 Collection<Integer> can be copied into Collection<Number> or Collection<Object>: source extends, destination super.
  • EX04 Arrays.stream(c.getDeclaredMethods()).filter(m -> m.isAnnotationPresent(Audited.class)) with RUNTIME retention.
  • EX05 The call is on this, bypassing the Spring proxy. Move b() to another bean, or inject the proxy (self-injection with care) or restructure.
  • EX06 Reflection is slower, mostly warm-up-dependent; cache Method objects or use MethodHandle/direct calls.

Quiz

Outcomes: O1 erasure · O2 PECS · O3 reflection and annotations · O4 proxies and Spring.

A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.

  1. 1At runtime List<String> is seen as:O1
  2. 2Which does not compile?O1
  3. 3Heap pollution typically shows up as:O1
  4. 4For a source you only read from, use:O2
  5. 5For a destination you add T to, use:O2
  6. 6An annotation readable by reflection needs:O3
  7. 7A fair concern about reflection is:O3
  8. 8A JDK dynamic proxy requires the target to implement:O4
  9. 9this.save() inside a Spring bean with @Transactional on save:O4
  10. 10Which gives annotation-driven behavior around calls in Spring?O4

Practical part

Six exercises MID-009-EX01 to EX06 plus the lab. Pass: at least five exercises correct, at least eight of the ten quiz questions right, and the lab showing the self-invocation limitation.

Common mistakes

Reflection in hot paths; raw types from erasure confusion.

Assessment

Exercises plus a proxy-behavior quiz.

Career relevance

Reading framework internals when debugging.

Type to search levels, phases, modules and lessons.