В дополнение к тому, что поля static
относятся к их классам, и, следовательно, существует только один экземпляр static
varaible для каждого класса (и для каждого загрузчика классов), важно понимать, что переменные static final
, инициализированные компиляцией постоянные выражения в реальном времени встроены в классы, которые их используют.
JLS §13.1 Форма двоичного файла :
Ссылки на поля, которые постоянные переменные (§4.12.4) разрешаются во время компиляции к постоянному значению, которое обозначается. Никакая ссылка на такое постоянное поле не должна присутствовать в коде в двоичном файле (кроме класса или интерфейса, содержащего поле констант, которое будет иметь код для его инициализации), и такие константные поля всегда должны быть инициализированы; начальное значение по умолчанию для типа такого поля никогда не должно наблюдаться.
blockquote>Таким образом, на практике экземпляр переменной
static final
, принадлежащий его классу, не является единственным экземпляром значение этой переменной - есть другие экземпляры этого значения, встроенные в константные пулы (или код) классов, которые используют рассматриваемую переменную.class Foo { public static final String S = "Hello, world!"; } class Bar { public static void main(String[] args) { // No real access to class Foo here // String "Hello, world!" is inlined into the constant pool of class Bar String s = Foo.S; System.out.println(s); } }
На практике это означает, что если вы измените значение
Foo.S
в классеFoo
, но не перекомпилируете классBar
, классBar
напечатает старое значениеFoo.S
.