Java: использование памяти ключевого слова final?

Когда вы объявляете переменную (константу) final в классе, например:

private static final int MyVar = 255;

Сколько потребуется памяти, если у меня есть 100 000 экземпляров класса, которые это объявили?

Связает ли эта переменная с классом и, таким образом, использует 1 * MyVar память (без учета внутренних указателей) или свяжется с экземпляром этой переменной и создаст 100 000 * MyVar-копий этой переменной?

Невероятно быстрый ответ! По-видимому, консенсус состоит в том, что если переменная является как статической, так и конечной, то для этого потребуется 1 * MyVar. Спасибо всем!

Ответ 1

Ключевое слово final не имеет значения для объема используемой памяти, поскольку это означает только, что вы не можете изменить значение переменной.

Однако, поскольку переменная объявлена ​​ static, будет только одна такая переменная, которая принадлежит классу, а не конкретному экземпляру.

Взято из здесь:

Если объявлено поле static, существует ровно одно воплощение поля, независимо от того, сколько экземпляров (возможно, нуль) класса может быть в конечном итоге создано. Статическое поле, иногда называемое переменной класса, воплощается при инициализации класса. Поле, которое не объявлено статическим (иногда называемое нестатическим полем), называется переменной экземпляра. Всякий раз, когда создается новый экземпляр класса, создается новая переменная, связанная с этим экземпляром для каждой переменной экземпляра, объявленной в этом классе или любом из ее суперклассов.

Ответ 2

Будет использовано только 1 * MyVar память, потому что объявлено как static.

Ответ 3

Статическое объявление означает, что у него будет только один экземпляр для этого класса, и он подклассы (если они не переопределяют MyVar).

int - это 32-битный подписанный 2-х целочисленный примитив, поэтому для его хранения требуется 4 байта, если в вашем примере не использовался static, вы просто умножаете его на количество экземпляров, которые у вас есть (для вашего примера из 100 000 экземпляров, что 0,38 мегабайта - только для поля, дополнительные накладные расходы для реальных классов).

Последний модификатор в поле означает, что он не может быть повторно назначен другому значению (тогда как final в классе метода означает, что его нельзя переопределить).

Ответ 4

Он статический и, следовательно, класс scope → 1.

Изменить: на самом деле это зависит от загрузчиков классов. В общем случае у вас есть одна копия класса, но если у вас есть несколько классных загрузчиков/репозитариев классов (может быть, это относится к серверам приложений и т.д.), Вы можете получить больше.

Ответ 5

В дополнение к тому, что поля static принадлежат их классам, и, следовательно, существует только один экземпляр static varaible для каждого класса (и для каждого загрузчика классов), важно понимать, что переменные static final, инициализированные компиляцией постоянные выражения встроены в классы, которые используют их.

JLS §13.1 Форма двоичного файла:

Ссылки на поля, которые являются постоянными переменными (§4.12.4), разрешаются во время компиляции к постоянному значению, которое обозначается. Никакая ссылка на такое постоянное поле не должна присутствовать в коде в двоичном файле (кроме класса или интерфейса, содержащего поле констант, которое будет иметь код для его инициализации), и такие константные поля всегда должны быть инициализированы; начальное значение по умолчанию для типа такого поля никогда не должно наблюдаться.

Таким образом, на практике экземпляр переменной 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.

Ответ 6

static означает, что у вас будет только один instatnce

final означает, что вы не можете переназначить это значение.

Ответ 7

Важнейшая часть здесь состоит в том, что вы объявили переменную как static, потому что статические переменные распределяются между всеми экземплярами класса, поэтому для этого требуется всего лишь одно пространство переменной. Объявление переменной final делает ее неизменной вне ее объявления или конструктора.

Ответ 8

final делает использование 1*instances памяти.

Однако static делает это просто 1.

Ответ 9

Ключевое слово "final" помогает вам объявить константу с определенным объемом памяти, где, поскольку ключевое слово "static" в качестве своего префикса даст один экземпляр этой константы, какой бы объем памяти не потреблялся..!!!

Ответ 10

Это статично, поэтому будет создан только один экземпляр, поэтому, как бы много байтов не потребовалось для хранения одного элемента int, будет выделено

Ответ 11

У вас будет один экземпляр для каждого класса. Если у вас есть класс, загруженный более одного раза (в разных загрузчиках классов), он будет загружен один раз за загрузчик классов, который загружает его.

Кстати: в наши дни память удивительна. Даже если на экземпляр была копия, время, требующее ответа на вопрос, стоит больше, чем память, которую вы сохраняете. Вы должны сделать это static final для ясности, а не для производительности. Более четкий код легче поддерживать и часто более эффективен.