diff --git a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java index 8cbfcc6f5a..5d3f9a4094 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java @@ -194,10 +194,38 @@ final class SynthesizedMergedAnnotationInvocationHandler i return string; } + /** + * This method currently does not address the following issues which we may + * choose to address at a later point in time. + * + * + * @param value the attribute value to format + * @return the formatted string representation + */ private String toString(Object value) { if (value instanceof String) { return '"' + value.toString() + '"'; } + if (value instanceof Character) { + return '\'' + value.toString() + '\''; + } + if (value instanceof Byte) { + return String.format("(byte) 0x%02X", value); + } + if (value instanceof Long) { + return Long.toString(((Long) value)) + 'L'; + } + if (value instanceof Float) { + return Float.toString(((Float) value)) + 'f'; + } + if (value instanceof Double) { + return Double.toString(((Double) value)) + 'd'; + } if (value instanceof Enum) { return ((Enum) value).name(); } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java index a6ff5a0f07..acd8fc9aba 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java @@ -1887,7 +1887,7 @@ class MergedAnnotationsTests { // Formatting common to Spring and JDK 9+ assertThat(string) - .contains("value={\"/test\"}", "path={\"/test\"}", "name=\"bar\"") + .contains("value={\"/test\"}", "path={\"/test\"}", "name=\"bar\"", "ch='X'", "chars={'X'}") .endsWith(")"); if (webMapping instanceof SynthesizedAnnotation) { @@ -1895,14 +1895,36 @@ class MergedAnnotationsTests { .startsWith("@org.springframework.core.annotation.MergedAnnotationsTests.RequestMapping(") .contains("method={GET, POST}", "clazz=org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod.class", - "classes={org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod.class}"); + "classes={int[][].class, org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod[].class}", + "byteValue=(byte) 0xFF", "bytes={(byte) 0xFF}", + "shortValue=9876", "shorts={9876}", + "longValue=42L", "longs={42L}", + "floatValue=3.14f", "floats={3.14f}", + "doubleValue=99.999d", "doubles={99.999d}" + ); } else { assertThat(string).as("JDK 9-18 formatting") .startsWith("@org.springframework.core.annotation.MergedAnnotationsTests$RequestMapping(") .contains("method={method: get, method: post}", "clazz=org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod.class", - "classes={org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod.class}"); + "classes={int[][].class, org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod[].class}", + "shortValue=9876", "shorts={9876}", + "floatValue=3.14f", "floats={3.14f}", + "doubleValue=99.999", "doubles={99.999}" + ); + if (JRE.currentVersion().ordinal() < JRE.JAVA_14.ordinal()) { + assertThat(string).as("JDK 9-13 formatting") + .contains("longValue=42", "longs={42}", + "byteValue=-1", "bytes={-1}" + ); + } + else { + assertThat(string).as("JDK 14+ formatting") + .contains("longValue=42L", "longs={42L}", + "byteValue=(byte)0xff", "bytes={(byte)0xff}" + ); + } } } @@ -2996,9 +3018,29 @@ class MergedAnnotationsTests { RequestMethod[] method() default {}; + // --------------------------------------------------------------------- + // All remaining attributes declare default values that are used solely + // for the purpose of testing the toString() implementations for annotations. Class clazz() default RequestMethod.class; + Class[] classes() default {int[][].class, RequestMethod[].class}; + + char ch() default 'X'; + char[] chars() default {'X'}; + + byte byteValue() default (byte) 0xFF; + byte[] bytes() default {(byte) 0xFF}; + + short shortValue() default 9876; + short[] shorts() default {9876}; + + long longValue() default 42L; + long[] longs() default {42L}; + + float floatValue() default 3.14F; + float[] floats() default {3.14F}; - Class[] classes() default {RequestMethod.class}; + double doubleValue() default 99.999D; + double[] doubles() default {99.999D}; } @Retention(RetentionPolicy.RUNTIME)