Interview
Reflection & Annotations — Interview Questions (72+)
Detailed Questions
1. What is reflection?
- Short: Inspect and invoke classes/methods/fields at runtime via
java.lang.reflect. - Detailed:
Class.forName,getDeclaredMethods,setAccessible(true),Method.invoke. Used by frameworks (Spring, Hibernate, Jackson) for dependency injection, ORM mapping, JSON binding. Bypasses compile-time checks. - Example:
obj.getClass().getMethod("foo", int.class).invoke(obj, 42);
2. How do you obtain a `Class` object?
- Short:
.class,obj.getClass(),Class.forName(name). - Detailed: Primitives have
int.class.forNameloads class (runs static init). Class objects are singletons per loader. - Example:
String.class == "hi".getClass().
3. getMethod vs getDeclaredMethod?
- Short:
getMethodincludes inherited public;getDeclaredall declared in class (any visibility). - Detailed: For private methods use
getDeclaredMethod+setAccessible(true).getMethodsreturns only public including inherited. - Example: Access private field in test via reflection (careful in production).
4. setAccessible and module system?
- Short: Java 9+ strong encapsulation;
--add-opensmay be required for JDK internals. - Detailed: Deep reflection on non-exported packages illegal by default. Frameworks use
opensin module-info or JVM flags. Prefer public API / MethodHandles over breaking encapsulation. - Example: Hibernate opens entity packages for bytecode access.
5. Annotations — retention and target?
- Short:
@Retention(RUNTIME|CLASS|SOURCE)and@Target(TYPE, METHOD, FIELD…). - Detailed: SOURCE = compile-time only (e.g.
@Override). CLASS = bytecode, not runtime. RUNTIME = visible to reflection (@Entity,@Autowired).@Inheritedon class annotations propagates to subclasses. - Example:
@Retention(RetentionPolicy.RUNTIME) @interface MyTag {}
6. Annotation processing — compile-time vs runtime?
- Short: APT generates code at compile (Lombok, MapStruct); runtime reflection reads annotations.
- Detailed: JSR 269 annotation processors inspect AST during
javac. Cleaner than runtime reflection for codegen. MapStruct generates mapper impls at compile time. - Example:
@Mapperinterface → generatedUserMapperImpl.
7. MethodHandles vs reflection?
- Short: MethodHandles are JVM-aware, faster, type-safe; preferred for repeated invocation.
- Detailed:
MethodHandles.lookup().findVirtual(...).LambdaMetafactoryuses handles for lambdas. Reflection easier for ad-hoc tools; handles for performance-critical paths. - Example:
metaprogramming5ReflectionVsHandles.java.
8. Dynamic proxies?
- Short:
Proxy.newProxyInstancecreates interface impl at runtime invokingInvocationHandler. - Detailed: Only interfaces, not classes (use ByteBuddy/CGLIB for classes). Used for mocking, transactions (
@Transactional), logging. - Example:
metaprogramming1DynamicProxy.java.
9. VarHandles (Java 9+)?
- Short: Typed, atomic field/array access without boxing.
- Detailed: Replacement for some
sun.misc.Unsafeuses. Support compare-and-set on fields. Used in concurrent collections internals. - Example: Low-level lock-free structures.
10. Common annotation examples in enterprise?
- Short:
@Override,@Deprecated,@SuppressWarnings,@FunctionalInterface, JPA@Entity, Spring@Component. - Detailed: JPA maps object model to tables. Spring stereotypes (
@Service,@Repository) enable component scan. Jackson@JsonPropertycontrols JSON. - Example: Stereotype meta-annotated with
@Component.
11. Repeatable annotations?
- Short:
@Repeatablewraps multiple same annotation in container. - Detailed:
@Schedules({@Schedule(...), @Schedule(...)})or repeated form Java 8+. Container annotation holds array. - Example: Multiple
@AttributeOverridein JPA.
12. Reflection performance cost?
- Short: First invoke slow (security checks); cache
Method/Fieldobjects; prefer handles or codegen. - Detailed:
setAccessiblereduces checks. Frameworks cache metadata at startup. Don't reflect in tight loops without caching. - Example: Spring caches bean metadata at context refresh.
Rapid-Fire (Q → A)
- Reflect private field? → getDeclaredField + setAccessible.
- Field.get object arg? → Instance field needs target; static null.
- invoke static method? → null as first arg to invoke.
- Constructor.newInstance? → Creates instance; exception wrapper.
- getConstructors vs declared? → Public only vs all.
- isAssignableFrom? → Subtype check.
- cast with Class? → class.cast(obj).
- instanceof with Class? → class.isInstance(obj).
- Array reflection? → Array.newInstance(component, len).
- Generic type erasure reflection? → Type interface for ParameterizedType.
- getGenericSuperclass? → For type tokens.
- Annotation on parameter? → getParameterAnnotations.
- Default annotation values? → annotation.defaultMember().
- Marker annotation? → No methods (@Deprecated style).
- Single-value annotation? → value() shorthand.
- @Documented? → Appears in javadoc.
- @Inherited class only? → Yes, not methods.
- @Repeatable container? → Holds annotation array.
- @Native annotation? → Native method marker.
- @SafeVarargs on? → Private/static/final varargs only.
- FunctionalInterface check? → Compiler + runtime optional.
- Proxy requires? → Interfaces only.
- InvocationHandler? → invoke(proxy, method, args).
- CGLIB proxy? → Subclass-based (Spring).
- ByteBuddy? → Modern bytecode generation.
- ASM library? → Low-level bytecode.
- javassist? → Bytecode editing.
- ClassLoader loadClass? → vs Class.forName static init.
- defineClass? → Custom class loaders.
- SPI ServiceLoader? → META-INF/services.
- double-checked reflection? → Cache lookup + Method object.
- SecurityManager reflection? → Deprecated/removed modern JDK.
- InaccessibleObjectException? → Module blocks access.
- --add-opens syntax? → --add-opens module/pkg=target-module.
- records reflection? → isRecord, getRecordComponents.
- sealed permits reflection? → getPermittedSubclasses.
- enum reflection? → getEnumConstants.
- AnnotationMirror compile? → Processor API.
- Element vs TypeElement? → AST model.
- Filer in processor? → Generate source files.
- Messager printMessage? → Compiler errors/warnings.
- Lombok how works? → Annotation processor codegen.
- MapStruct how? → Processor generates mappers.
- Hibernate bytecode? → ByteBuddy enhancement.
- Jackson annotations runtime? → RUNTIME retention.
- JAX-RS annotations? → Runtime for REST mapping.
- Validation @NotNull? → Bean Validation runtime.
- ConstraintValidator? → Custom validation logic.
- CDI @Inject? → Jakarta EE DI.
- Qualifier annotation? → Disambiguate beans.
- @Primary Spring? → Default bean choice.
- @ConditionalOnProperty? → Boot auto-config condition.
- Meta-annotation? → Annotation on annotation.
- @AliasFor? → Attribute alias in Spring.
- Kotlin reflection separate? → kotlin.reflect.
- GraalVM native reflection? → Registration config needed.
- reachability metadata? → Native image reflect config.
- serialization reflect? → Reflective access to private ctor.
- Unsafe status? → Internal; use VarHandle/Foreign API.
- Foreign Function API? → Panama native interop.