Java is the same enumeration with different values

I use the enumeration to identify several options that can be added to the product (custom logo, colors, etc.). Each option has several options (identifier, description in two languages, where changes are made in the process, price, etc.). It has methods for further defining a change (for example, which color should be used) or for overriding certain parameters. A single product can have either zero or one or more options stored in an ArrayList. Also, one option can be applied more than once.

While I use the option only once, everything is in order. But in case I use it more than once, it seems that everyone gets the same options.

Code example:

TestClass.java:

import java.util.ArrayList; public class TestClass { public static void main(String[] args) { ArrayList<TestEnum> enums = new ArrayList<>(); TestEnum enumVar; enumVar = TestEnum.TEST1; enums.add(enumVar); enumVar = null; enumVar = TestEnum.TEST2; enums.add(enumVar); enumVar = null; enumVar = TestEnum.TEST2; enumVar.setOp1("new op21"); enumVar.setOp2("new op22"); enumVar.setOp3("new op23"); enums.add(enumVar); enumVar = null; enums.forEach((element) -> { System.out.println("op1: " + element.getOp1() + "; op2: " + element.getOp2() + "; op3: " + element.getOp3()); /* Expecting: op1: op11; op2: op12; op3: op13 op1: op21; op2: op22; op3: op23 op1: new op21; op2: new op22; op3: new op23 Output: op1: op11; op2: op12; op3: op13 op1: new op21; op2: new op22; op3: new op23 op1: new op21; op2: new op22; op3: new op23 */ }); } } 

TestEnum.java:

 public enum TestEnum { TEST1("op11", "op12", "op13"), TEST2("op21", "op22", "op23"), TEST3("op31", "op32", "op33"), TEST4("op41", "op42", "op43"), TEST5("op51", "op52", "op53"); private String op1; private String op2; private String op3; TestEnum(String op1, String op2, String op3) { this.op1 = op1; this.op2 = op2; this.op3 = op3; } public void setOp1(String op1) { this.op1 = op1; } public String getOp1() { return this.op1; } public void setOp2(String op2) { this.op2 = op2; } public String getOp2() { return this.op2; } public void setOp3(String op3) { this.op3 = op3; } public String getOp3() { return this.op3; } } 

Is it possible to do what I mean with an enumeration?

If so, what am I doing wrong? Maybe it is possible to create a copy of the listing in a certain state?

+8
java enums
source share
5 answers

No, enumerations are not suitable for describing objects that are similar but have different states.

The continuum constants are static. You do not have two different instances of TEST1 . You only have one. Both list items related to TEST2 in your example are for the same instance. This is not a copy, this is the second link.

To have instances that are similar but have slightly different states, you must declare a class, not an enumeration. You can use the enumeration to describe the type of change (for example, COLOR_VARIATION , CUSTOM_LOGO ). You can have two different classes that extend a class called Variation or use it directly - it depends on whether the implementation details are different. But you will use new Variation(...) or use the static factory method to create a new Variation instance, and then each Variation instance can have a different set of values ​​in its fields, even if they are both of the same “change type”.

+6
source share

No, you cannot do this with listings. There is always one instance of each enumeration value. If you change the data in an enumeration (for example, one of your setOpn() methods), it will be changed globally because there is only one.

It is best to make the data in the rename immutable. Then, for variable parameters, you can associate an ArrayList with each thing that has parameters and assign it one of the enumerations.

You can do it as follows:

 public class ThingWithOptionsAndEnum { private final TestEnum myBaseOptions; private final ArrayList<String> myAdditionalOptions = new ArrayList<>(); public ThingWithOptionsAndEnum(final TestEnum base, String... options) { this.myBaseOptions = base; if (options != null) { for (String option : options) { myAdditionalOptions.add(option); } } } } 
+8
source share

The other answers on this page are most likely correct, but may not help you solve your problem.

Instead of listing, try implementing a simple old class, but include the clone() method. You can then create several “standard” class instances, each of which represents the default product configuration. When the user selects a specific product configuration, you call clone() on the main object, then you can just use regular setters to modify the object here.

Check out the prototype design pattern. The whole idea is to use these "magic" objects to create new copies, which can then be changed. I think this may be a little more than what you are looking for. https://en.wikipedia.org/wiki/Prototype_pattern

+8
source share

There is only one instance of each enumeration value. Think of them as global variables used by the compiler.

 enumVar = TestEnum.TEST2; enums.add(enumVar); enumVar = null; enumVar = TestEnum.TEST2; enumVar.setOp1("new op21"); enumVar.setOp2("new op22"); enumVar.setOp3("new op23"); enums.add(enumVar); enumVar = null; 

Firstly, explicitly nulling an enumVar link enumVar nothing. Secondly, when you reference TestEnum.TEST2 , you point to the same value in both blocks - this means that your subsequent calls to setOp overwrite the previous values.

+2
source share

As a rule, an enumeration is invariant by definition. By adding setters to your enumeration, you make it an option.

As for your question, this is because you have the same reference to TEST2 in your array. Since this is a link, the second and third elements are the same. Therefore, if you modify any element of TEST2 , another link reflects the change.

To test this, you can switch the destination lines ( enumVar.setOp1 ) from the third to the second element, and you will see the same behavior.

It looks like you have converted an enumeration into an object.

+1
source share

All Articles