I create an interface with constants and a final-array that contains these constants:

interface SozKonstants{ public static final String ONE="one"; public static final String TWO="two"; public static final String THRE="thre"; public static final String[] NUMBER={ONE,TWO,THRE}; } 

But the elementary assignment works, the compiler does not swear that "an attempt was made to change the final variable"

 public class SomeClass{ public static void main(String[] args){ System.out.println(SozKonstants.NUMBER[1]); SozKonstants.NUMBER[1]="ten"; System.out.println(SozKonstants.NUMBER[1]); } } 

I can not understand where was wrong and how to make sure that the compiler does not miss the replacement values ​​in the array.

  • one
    I will add advice to the answers, - see examples of using enumarations, it is quite possible that the NUMBER array can be abandoned. since enum has a static method values ​​() which returns an array with all valid constants, which is very convenient if you need to iterate to process all constants. - jmu

2 answers 2

The final keyword prohibits changing the value after initialization. The value of the variable String[] NUMBER is not the array itself, but a reference to the array. Accordingly, after initialization, do this:

 SozKonstants = new String[5]; 

you can no longer. At the same time, no restrictions on read-write are imposed on the elements of the array, since they are not independent named variables.

If you need a container with immutable objects, use immutable collections from Google Guava or unmodifiable from Apache Commons Collections .


UPD0. You can also take advantage of the fact that instances of the enumerated type are full-fledged classes. This will allow you to make an enum with a limited set of elements, each of which stores some additional value. Like that:

 public enum SozKonstants { ONE("one"), TWO("two"), THREE("three"); private String val; private SozKonstants(String value) { val = value; } public String getVal() { return val; } } public class SomeClass{ public static void main(String[] args){ System.out.println(SozKonstants.ONE.getVal()); SozKonstants.ONE ... //ввернуть в enum значение уже не получится (если вы, конечно, не сделаете сеттер для val) } } 

    I understand the goal is that the array of constants is final , so if you can try to get confused through enum and do this:

     interface SozKonstants { public static final String ONE="One"; public static final String TWO="Two"; public static final String THREE="Three"; public static enum Numbers { ONE { public String toString() { return SozKonstants.ONE; } }, TWO { public String toString() { return SozKonstants.TWO; } }, THREE { public String toString() { return SozKonstants.THREE; } } } public static final String[] NUMBER= { Numbers.ONE.toString(), Numbers.TWO.toString(), Numbers.THREE.toString() }; }