LexicographicalAnnotationAttributeListing
SUGGESTION
Style
Summary
Where possible, sort annotation array attributes lexicographically
Suppression
Suppress false positives by adding the suppression annotation
@SuppressWarnings("LexicographicalAnnotationAttributeListing")
to the enclosing element.Disable this pattern completely by adding
-Xep:LexicographicalAnnotationAttributeListing:OFF
as compiler argument. Learn more.
Samples
Replacement
Shows the difference in example code before and after the bug pattern is applied.
import static java.math.RoundingMode.DOWN;
import static java.math.RoundingMode.UP;
import java.math.RoundingMode;
interface A {
@interface Foo {
String[] value() default {};
boolean[] bools() default {};
char[] chars() default {};
Class<?>[] cls() default {};
RoundingMode[] enums() default {};
Bar[] anns() default {};
}
@interface Bar {
String[] value() default {};
}
- @Foo({" ", "", "b", "a"})
+ @Foo({"", " ", "a", "b"})
A unsortedStrings();
- @Foo(bools = {true, false})
+ @Foo(bools = {false, true})
A unsortedBooleans();
- @Foo(chars = {'b', 'a'})
+ @Foo(chars = {'a', 'b'})
A unsortedChars();
- @Foo(cls = {long.class, int.class})
+ @Foo(cls = {int.class, long.class})
A unsortedClasses();
- @Foo(enums = {UP, DOWN})
+ @Foo(enums = {DOWN, UP})
A unsortedEnums();
- @Foo(anns = {@Bar("b"), @Bar("a")})
+ @Foo(anns = {@Bar("a"), @Bar("b")})
A unsortedAnns();
- @Foo(anns = {@Bar("a"), @Bar({"b", "a"})})
+ @Foo(anns = {@Bar("a"), @Bar({"a", "b"})})
A unsortedInnderAnns();
}
Identification
Shows code lines which will (not) be flagged by this bug pattern.
A //BUG: Diagnostic contains:
comment is placed above any violating line.
import static java.math.RoundingMode.DOWN;
import static java.math.RoundingMode.UP;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import java.math.RoundingMode;
import javax.xml.bind.annotation.XmlType;
import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.TestPropertySource;
interface A {
@interface Foo {
String[] value() default {};
boolean[] bools() default {};
char[] chars() default {};
int[] ints() default {};
Class<?>[] cls() default {};
RoundingMode[] enums() default {};
Bar[] anns() default {};
}
@interface Bar {
String[] value() default {};
}
@Foo({})
A noString();
@Foo({"a"})
A oneString();
@Foo({"a", "b"})
A sortedStrings();
// BUG: Diagnostic contains:
@Foo({"b", "a"})
A unsortedString();
@Foo({"ab", "Ac"})
A sortedStringCaseInsensitive();
// BUG: Diagnostic contains:
@Foo({"ac", "Ab"})
A unsortedStringCaseInsensitive();
@Foo({"A", "a"})
A sortedStringCaseInsensitiveWithTotalOrderFallback();
// BUG: Diagnostic contains:
@Foo({"a", "A"})
A unsortedStringCaseInsensitiveWithTotalOrderFallback();
@Foo(bools = {})
A noBools();
@Foo(bools = {false})
A oneBool();
@Foo(bools = {false, true})
A sortedBools();
// BUG: Diagnostic contains:
@Foo(bools = {true, false})
A unsortedBools();
@Foo(chars = {})
A noChars();
@Foo(chars = {'a'})
A oneChar();
@Foo(chars = {'a', 'b'})
A sortedChars();
// BUG: Diagnostic contains:
@Foo(chars = {'b', 'a'})
A unsortedChars();
@Foo(ints = {})
A noInts();
@Foo(ints = {0})
A oneInt();
@Foo(ints = {0, 1})
A sortedInts();
@Foo(ints = {1, 0})
A unsortedInts();
@Foo(cls = {})
A noClasses();
@Foo(cls = {int.class})
A oneClass();
@Foo(cls = {int.class, long.class})
A sortedClasses();
// BUG: Diagnostic contains:
@Foo(cls = {long.class, int.class})
A unsortedClasses();
@Foo(enums = {})
A noEnums();
@Foo(enums = {DOWN})
A oneEnum();
@Foo(enums = {DOWN, UP})
A sortedEnums();
// BUG: Diagnostic contains:
@Foo(enums = {UP, DOWN})
A unsortedEnums();
@Foo(anns = {})
A noAnns();
@Foo(anns = {@Bar("a")})
A oneAnn();
@Foo(anns = {@Bar("a"), @Bar("b")})
A sortedAnns();
// BUG: Diagnostic contains:
@Foo(anns = {@Bar("b"), @Bar("a")})
A unsortedAnns();
// BUG: Diagnostic contains:
@Foo(anns = {@Bar("a"), @Bar({"b", "a"})})
A unsortedInnderAnns();
@Foo({"a=foo", "a.b=bar", "a.c=baz"})
A hierarchicallySorted();
// BUG: Diagnostic contains:
@Foo({"a.b=bar", "a.c=baz", "a=foo"})
A hierarchicallyUnsorted();
@JsonPropertyOrder({"field2", "field1"})
A dto();
@ApiImplicitParams({@ApiImplicitParam("p2"), @ApiImplicitParam("p1")})
A firstEndpoint();
@Parameters({@Parameter(name = "p2"), @Parameter(name = "p1")})
A secondEndpoint();
@XmlType(propOrder = {"field2", "field1"})
class XmlTypeDummy {}
@PropertySource({"field2", "field1"})
class PropertySourceDummy {}
@TestPropertySource(locations = {"field2", "field1"})
class FirstTestPropertySourceDummy {}
@TestPropertySource({"field2", "field1"})
class SecondTestPropertySourceDummy {}
}
package pkg;
interface A {
@interface Foo {
String[] value() default {};
String[] value2() default {};
}
@interface Bar {
String[] value() default {};
String[] value2() default {};
}
@interface Baz {
String[] value() default {};
String[] value2() default {};
}
// BUG: Diagnostic contains:
@Foo({"b", "a"})
A fooValue();
// BUG: Diagnostic contains:
@Foo(value2 = {"b", "a"})
A fooValue2();
@Bar({"b", "a"})
A barValue();
// BUG: Diagnostic contains:
@Bar(value2 = {"b", "a"})
A barValue2();
@Baz({"b", "a"})
A bazValue();
@Baz(value2 = {"b", "a"})
A bazValue2();
}