JDK-8281462 : Annotation toString output for enum not reusable for source input
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-02-08
  • Updated: 2022-02-15
  • Resolved: 2022-02-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 19
19 masterFixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Description
As a follow up to JDK-8162817, if an enum used in an annotation has overridden `toString()` to return something other than `name()`, the output of the annotation's `toString()` method will not be reusable for source input.

Given the following example application:

-------------------------------------------------------------------------
package example;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

public class Example {

	enum Color {
		RED, GREEN, BLUE;

		public String toString() {
			return name().toLowerCase();
		}
	}

	@Retention(RetentionPolicy.RUNTIME)
	@interface Colors {
		Color[] value();
	}

	@Colors({Color.RED, Color.BLUE})
	public static void main(String[] args) throws Exception {
		Method method = Example.class.getDeclaredMethod("main", String[].class);
		System.out.println(method.getAnnotation(Colors.class));
	}
}
-------------------------------------------------------------------------

The output of the application on JDK 9 through JDK 17 is:

@example.Example$Colors({red, blue})

Whereas, we would expect the output to be:

@example.Example$Colors({RED, BLUE})

Or potentially using partially qualified enum constants as in:

@example.Example$Colors({Color.RED, Color.BLUE})

Or potentially using fully qualified enum constants as in:

@example.Example$Colors({example.Example.Color.RED, example.Example.Color.BLUE})

The cause for this is the fact that `Enum#toString()` is invoked instead of `Enum#name()` when generating the output of each enum constant in the `toString()` implementation of `Annotation`.
Comments
Changeset: c3179a87 Author: Joe Darcy <darcy@openjdk.org> Date: 2022-02-11 23:24:08 +0000 URL: https://git.openjdk.java.net/jdk/commit/c3179a8760019b5954e344bf0d2775e1e1968f32
11-02-2022

The annotation printing in javac already uses the names of enum constants rather than their toString values as well as using canonical type names rather than binary names.
11-02-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/7418 Date: 2022-02-10 05:49:47 +0000
10-02-2022

As a side note, for a nested annotation type such as `Colors` in the provided example, I would expect the `toString()` to output `@example.Example.Colors(...)` using the canonical name instead of `@example.Example$Colors(...)` using the binary name.
08-02-2022