Да, они константы времени компиляции. Например, код
private static final boolean DEBUG = false;
...
if (DEBUG) {
// some code
}
будет скомпилировано в байт-код, который даже не содержит код внутри if
. Он будет удален компилятором.
И вам нужно перекомпилировать все классы, ссылающиеся на константу, если вы решите изменить ее значение.
Обратите внимание, что это только ссылка, которую нельзя изменить. Содержимое объекта (если оно изменчиво) может быть изменено. Например, содержимое массива или StringBuilder в следующем коде может быть изменено:
// don't do this:
public static final String[] seasons = new String[] {"Spring", "Summer", "Autumn", "Winter"};
public static final StringBuilder someBuffer = new StringBuilder("foo");
Ваш вопрос о перечислениях не имеет смысла. Нет перечисления примитива или STring. Каждое перечисление определяет свой собственный класс.