ContentType (Java SE 25 & JDK 25)
Description: declaration: module: jdk.jfr, package: jdk.jfr, annotation type: ContentType
Keywords: jdk.jfr.ContentType class

# Annotation Interface ContentType

@Target(ANNOTATION_TYPE) @Retention(RUNTIME) public @interface ContentType
Meta annotation, specifies that an annotation represents a content type, such as a time span or a frequency.

The following example shows how a temperature content type can be created and used.

First declare a temperature annotation using the `ContentType` annotation:

    @MetadataDefinition
    @ContentType
    @Name("com.example.Temperature")
    @Label("Temperature")
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Temperature {
        public static final String KELVIN = "KELVIN";
        public static final String CELSIUS = "CELSIUS";
        public static final String FAHRENEHIT = "FAHRENHEIT";

        String value() default CELSIUS;
    }

Then declare an event, annotate a field and commit the data:

    @Name("com.example.CPU")
    @Label("CPU")
    @Category({ "Hardware", "CPU" })
    @Period("1 s")
    @StackTrace(false)
    public static class CPUEvent extends Event {
        @Label("ID")
        String id;

        @Temperature(Temperature.KELVIN)
        @Label("Temperature")
        float temperature;
    }

    public static void main(String... args) throws InterruptedException {
        FlightRecorder.addPeriodicEvent(CPUEvent.class, () -> {
            for (var cpu : listCPUs()) {
                CPUEvent event = new CPUEvent();
                event.id = cpu.id();
                event.temperature = cpu.temperature(); // in Kelvin
                event.commit();
            }
        });
        Thread.sleep(10_000);
    }

Finally, inspect the annotation when displaying event data:

    void printTemperaturesInCelsius(Path file) throws IOException {
        for (RecordedEvent event : RecordingFile.readAllEvents(file)) {
            for (ValueDescriptor field : event.getEventType().getFields()) {
                for (AnnotationElement ae : field.getAnnotationElements()) {
                    ContentType type = ae.getAnnotation(ContentType.class);
                    if (type != null) {
                        if (ae.getTypeName().equals("com.example.Temperature")) {
                            double value = event.getDouble(field.getName());
                            String unit = (String) ae.getValue("value");
                            double celsius = switch (unit) {
                                case "CELSIUS" -> value;
                                case "KELVIN" -> value - 273.15;
                                case "FAHRENHEIT" -> (value - 32) / 1.8;
                                default -> throw new IllegalStateException("Unknown temperature unit '" + unit + "'");
                            };
                            System.out.println(celsius + " C");
                        } else {
                            System.err.println("Can't format content type " + ae.getTypeName() + " for field " + field.getName());
                        }
                    }
                }
            }
        }
    }

Since:
  9