Java: использование памяти последнего ключевого слова? - PullRequest
15 голосов
/ 11 апреля 2011

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

private static final int MyVar = 255;

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

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

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

Ответы [ 12 ]

19 голосов
/ 11 апреля 2011

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

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

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

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

12 голосов
/ 11 апреля 2011

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

4 голосов
/ 11 апреля 2011

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

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

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

3 голосов
/ 11 апреля 2011

Это статично и, следовательно, область видимости -> 1.

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

2 голосов
/ 11 апреля 2011

В дополнение к тому факту, что поля 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.

1 голос
/ 14 апреля 2014

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

1 голос
/ 11 апреля 2011

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

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

1 голос
/ 11 апреля 2011

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

1 голос
/ 11 апреля 2011

static означает, что у вас будет только один экземпляр

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

0 голосов
/ 12 июля 2018

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...