为枚举字符串值定义常量“值”

时间:2019-08-29 07:20:37

标签: java enums sonarqube

对于如下定义的枚举

public enum Cars {

    SWIFT("Maruti"),
    DZIRE("Maruti"), 
    CIAZ("Maruti"), 
    I10("Hyundai"), 
    CRETA("Hyundai");

    String company;
    Cars(String company){
        this.company = company;
    }   
}

有声纳错误

Define a constant instead of duplicating this literal "Maruti" 3 times.

如果定义静态字符串,它将无法编译

Cannot reference a field before it is defined

解决方案1:

public enum Cars {

    SWIFT(CarsString.MARUTI.companyName),DZIRE("Maruti"), I10("Hyundai"), CRETA("Hyundai");

    static String MARUTI = "Maruti";
    String company;
    Cars(String company){
        this.company = company;
    }

    enum CarsString {
        MARUTI("maruti"),
        HYUNDAI("Hyundai");
        String companyName;
        CarsString(String companyName){
            this.companyName = companyName;
        }
    }
}

解决方案2:

不确定这是否是我们这样做的方式。如果Cars.MARUTI未引用该文件,则会出错Cannot reference a field before it is defined

public enum Cars {

    SWIFT(Cars.MARUTI),DZIRE(Cars.MARUTI), I10("Hyundai"), CRETA("Hyundai");

    public static final String MARUTI = "Maruti";
    String company;
    Cars(String company){
        this.company = company;
    }
 }

我有10个处于类似状态的枚举,并且上述解决方案1并没有太大地鼓励我。解决方案2解决了这个问题,

  

但是为什么我们要用Cars.MARUTI而不是MARUTI直接引用?这是一个限制吗?

我们如何在枚举中引用一个常量值?

2 个答案:

答案 0 :(得分:5)

如何在自己的Enum中定义公司?例如:

\d

更新:根据@Basil Bourque的评论,改进了命名约定!

答案 1 :(得分:2)

您需要了解枚举在内部如何工作。如果您查看枚举的字节码,您将得到答案。

 6: iconst_0
   7: ldc           #19                 // String Maruti
   9: invokespecial #21                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
  12: putstatic     #25                 // Field SWIFT:Labc/Cars;
  15: new           #1                  // class abc/Cars
  18: dup
  19: ldc           #27                 // String DZIRE
  21: iconst_1
  22: ldc           #19                 // String Maruti
  24: invokespecial #21                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
  27: putstatic     #28                 // Field DZIRE:Labc/Cars;
  30: new           #1                  // class abc/Cars
  33: dup
  34: ldc           #30                 // String CIAZ
  36: iconst_2:

从上面的byte code(由Cars枚举生成)中,我们可以得到一个类似于Cars enum

的类
class Foo {
    public static Cars SWIFT = new Cars("Maruti");
    public static Cars DZIRE = new Cars("Maruti");
    public static Cars CIAZ = new Cars("Maruti");
}

现在,如果将代码更改为:

class Cars {

    public static Cars SWIFT = new Cars(MARUTI); //statement-1
    public static Cars DZIRE = new Cars(MARUTI); //statement-2
    public static Cars CIAZ = new Cars(MARUTI); //statement-3

    public static String MARUTI = "Maruti"; // statement-4


    private String name;

    public Cars(String name) {
        this.name = name;
    }
}

由于您正在使用variable before it is defined,它会给您同样的错误消息。如果我们在statement-4之前将statement-1向上移动,它将起作用。但这是only possible in class but enum does not allow you as the first语句。因此,在您的情况下,您可以像这样进行解决:

enum Cars {

    SWIFT(Constants.MARUTI), DZIRE(Constants.MARUTI), I10("Hyundai"), CRETA("Hyundai");

    String company;

    Cars(String company) {
        this.company = company;
    }

    private static class Constants {

        public static String MARUTI = "Maruti";
    }
}