If a field is not a primitive constant, then deleting the keyword final or changing the value to which the field is initialized does not break compatibility with existing binaries. If a field is a primitive constant, then deleting the keyword final or changing its value will not break compatibility with pre-existing binaries by causing them not to run, but they will not see any new value for the constant unless they are recompiled. Other than for true mathematical constants, we recommend that Java code make very sparing use of class variables that are declared static and final . If the read-only nature of final is required, a better choice is to declare a private static variable and a suitable accessor method to get its value. We also recommend, as a general rule, that only truly constant values be declared in interfaces.
Similar idioms exist for the other primitive types.
If a field that is not declared private was not declared static and is changed to be declared static , or vice versa, then a linkage time error, specifically an IncompatibleClassChangeError , will result if the field is used by a preexisting binary which expected a field of the other kind. Such changes are not recommended in code that has been widely distributed. 13.4.10 transient Fields Adding or deleting a transient modifier of a field does not break compatibility with pre-existing binaries. If a field that is not declared private was not declared volatile and is changed to be declared volatile , or vice versa, then a linkage time error, specifically an IncompatibleClassChangeError , may result if the field is used by a preexisting binary that expected a field of the opposite volatility. Such changes are not recommended in code that has been widely distributed.