CodeBlanks Logo Icon CodeBlanks

Reflection and annotation

Write configuration with reflection and annotations.

Annotation with @interface

In this lesson you will define a custom annotation. @interface creates a marker type. String value() declares a single property.

@interface Logged {
    String value();
}

You mark a method with @Logged("audit"). The value can later be read with reflection. This is a clean way to add metadata to code.

Calling methods via reflection

With reflection you can find and call a class's methods at runtime. getMethod("describe") looks up by name; invoke calls it on an instance.

Method m = EventService.class.getMethod("describe");
String result = (String) m.invoke(service);
Logged logged = m.getAnnotation(Logged.class);
System.out.println(logged.value());

Here the @Logged annotation value audit is read. This shows the annotation-based marking and reading flow.

Practice Print describe and the @Logged value via reflection

The EventService class has a describe method marked with @Logged("audit"). Look up the method with Method m = EventService.class.getMethod("describe");. Call it with m.invoke(service) and print the result. Get the annotation with m.getAnnotation(Logged.class) and print value().

Starter code

Main.java
import java.util.ArrayList;

class Event {
    String type;
    int severity;
    Event(String type, int severity) {
        this.type = type;
        this.severity = severity;
    }
}

@interface Logged {
    String value();
}

class EventService {
    @Logged("audit")
    public String describe() {
        return "event-service";
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        // Call EventService.describe via reflection
        // Print the @Logged annotation value
    }
}

Sample solution

Main.java
import java.util.ArrayList;
import java.lang.reflect.*;

class Event {
    String type;
    int severity;
    Event(String type, int severity) {
        this.type = type;
        this.severity = severity;
    }
}

@interface Logged {
    String value();
}

class EventService {
    @Logged("audit")
    public String describe() {
        return "event-service";
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        EventService service = new EventService();
        Method m = EventService.class.getMethod("describe");
        String result = (String) m.invoke(service);
        Logged logged = m.getAnnotation(Logged.class);
        System.out.println(result);
        System.out.println(logged.value());
    }
}

Expected output

event-service
audit

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Complete the annotation definition

Question
@interface Logged {
    String ____();
}
Answer
@interface Logged {
    String value();
}

Explanation: value() is the single property of the annotation.

2 What does getMethod("describe") return?

  • A Method object Correct answer
  • A String
  • An int
  • A Class

Explanation: getMethod returns a Method object.

3 Match the reflection concepts

Term Meaning
@interface Annotation definition
getMethod Looks up by name
invoke Calls the method
getAnnotation Reads the annotation

All lessons in Advanced