For the enum defined as below
public enum Cars {
SWIFT("Maruti"),
DZIRE("Maruti"),
CIAZ("Maruti"),
I10("Hyundai"),
CRETA("Hyundai");
String company;
Cars(String company){
this.company = company;
}
}
There is Sonar error
Define a constant instead of duplicating this literal "Maruti" 3 times.
If we define static string, it fails to compile
Cannot reference a field before it is defined
Solution 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;
}
}
}
Solution 2:
Not sure if this is the way we do it. When it is not referenced by Cars.MARUTI, it errors out 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;
}
}
I have 10 enums in similar state and the above solution 1 didn't much encourage me. Solution 2 solves the purpose,
but why should we refer by
Cars.MARUTI
and notMARUTI
directly? is that a limitation ?
How could we refer a constant value in enum ?
To create an enum, use the enum keyword (instead of class or interface), and separate the constants with a comma. values() method can be used to return all values present inside enum.
The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.
An enum type is a special data type that enables for a variable to be a set of predefined constants.
We can't define enumeration as string type. The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.
What about defining the company in its own Enum? For example:
public enum Car {
SWIFT(Company.MARUTI),
DZIRE(Company.MARUTI),
CIAZ(Company.MARUTI),
I10(Company.HYUNDAI),
CRETA(Company.HYUNDAI);
Company company;
Cars(Company company) {
this.company = company;
}
}
public enum Company {
HYUNDAI("Hyundai"),
MARUTI("Maruti");
String name;
Company(String name) {
this.name = name;
}
}
Update: improved naming conventions according to comment of @Basil Bourque, thx!
You need to know how enum works internally. If you look at the byte code of your enum you will have the answer.
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:
From the above byte code
(which was generated from Cars enum), we can have a class which will be similar to the 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");
}
Now if you change the code to :
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;
}
}
It will give you the same error message because you are using the variable before it is defined
. If we move up the statement-4
before statement-1
it will work. But it is only possible in class but enum does not allow you as the first
statement.So in your case you can solve like :
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";
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With