Почему статические переменные считаются злыми? - PullRequest
585 голосов
/ 11 августа 2011

Я программист на Java, новичок в корпоративном мире.Недавно я разработал приложение с использованием Groovy и Java.Весь код, который я написал, использовал довольно много статики.Старшая техническая партия попросила меня сократить количество используемой статики.Я примерно так же гуглил и обнаружил, что многие программисты против использования статических переменных.

Я считаю, что статические переменные более удобны в использовании.И я предполагаю, что они тоже эффективны (пожалуйста, исправьте меня, если я ошибаюсь), потому что, если бы мне пришлось сделать 10000 вызовов функции внутри класса, я был бы рад сделать метод статичным и использовать прямое Class.methodCall() наэто вместо того, чтобы загромождать память 10 000 экземплярами класса, верно?

Более того, статика уменьшает взаимозависимости в других частях кода.Они могут выступать в качестве идеальных государственных держателей.В дополнение к этому я обнаружил, что статика широко применяется в некоторых языках, таких как Smalltalk и Scala .Так почему же это угнетение статики распространено среди программистов (особенно в мире Java)?

PS: пожалуйста, исправьте меня, если мои предположения о статике неверны.

Ответы [ 29 ]

3 голосов
/ 05 января 2014

В вашем сообщении есть два основных вопроса.

Сначала о статических переменных. Статические переменные совершенно не нужны, и их легко избежать. В языке ООП в целом, и в частности в Java, параметры функции передаются по ссылке, то есть, если вы передаете объект в функцию, вы передаете указатель на объект, поэтому вам не нужно определять статические переменные, так как Вы можете передать указатель на объект в любую область, которая нуждается в этой информации. Даже если это подразумевает, что yo заполнит вашу память указателями, это не обязательно будет означать низкую производительность, потому что реальные системы разбивки памяти оптимизированы для работы с этим, и они будут сохранять в памяти страницы, на которые ссылаются указатели, которые вы передали новому. объем; использование статических переменных может привести к тому, что система загрузит страницу памяти, где они хранятся, когда к ним необходимо получить доступ (это произойдет, если страница не была принята в течение длительного времени). Хорошей практикой является объединение всех этих статических компонентов в несколько маленьких «разделов конфигурации», это гарантирует, что система поместит все это на одну и ту же страницу памяти.

Во-вторых, о статических методах. Статические методы не так уж и плохи, но они могут быстро снизить производительность. Например, подумайте о методе, который сравнивает два объекта класса и возвращает значение, указывающее, какой из объектов больше (типичный метод сравнения), этот метод может быть статическим или нет, но при вызове его нестатическая форма будет более эффективной. поскольку он должен будет решить только две ссылки (по одной для каждого объекта) лицом к трем ссылкам, которые должны будут решить статическую версию одного и того же метода (одна для класса плюс две, одна для каждого объекта). Но, как я уже сказал, это не так уж плохо, если мы посмотрим на класс Math, мы сможем найти много математических функций, определенных как статические методы. Это действительно более эффективно, чем помещать все эти методы в класс, определяющий числа, потому что большинство из них используются редко, и включение их всех в класс чисел приведет к тому, что класс будет очень сложным и потребит много ресурсов без необходимости.

В заключение: избегайте использования статических переменных и находите правильное равновесие производительности при работе со статическими или нестатическими методами.

PS: простите за мой английский.

3 голосов
/ 11 августа 2011

а) Причина о программах.

Если у вас есть программа от малого до среднего размера, к которой обращаются к статической переменной Global.foo, вызов к ней обычно происходит из ниоткуда - нет пути и, следовательно, нет временной шкалы, как переменная попадает на место где это используется. Теперь, как я узнаю, кто установил его действительное значение? Как я узнаю, что произойдет, если я изменю это прямо сейчас? У меня есть grep для всего источника, чтобы собрать все доступы, чтобы знать, что происходит.

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

б) Вам действительно нужен только один?

Статические переменные часто не позволяют нескольким программам одного типа работать в одной и той же JVM с разными значениями. Вы часто не предвидите использования, когда более чем один экземпляр вашей программы полезен, но если он развивается или полезен для других, они могут столкнуться с ситуациями, когда они хотели бы запустить более одного экземпляра вашей программы. ,

Только более или менее бесполезный код, который не будет интенсивно использоваться многими людьми в течение более длительного времени, может хорошо сочетаться со статическими переменными.

3 голосов
/ 16 августа 2011

все (может :) имеет свое назначение, если у вас есть куча потоков, которым необходимо совместно использовать / кэшировать данные, а также всю доступную память (так что вы не разбиваетесь на контексты внутри одна JVM) статика - лучший выбор

-> конечно, вы можете использовать только один экземпляр, но почему?
я нахожу некоторые комментарии в этой теме злыми, а не статиками;)

2 голосов
/ 25 апреля 2017

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

Проблемы возникают при попытке использовать статические переменные для хранения значений, связанных с экземпляром.

2 голосов
/ 11 августа 2011

Все ответы выше показывают, почему статика плохая. Причина, по которой они злые , заключается в том, что создается ложное впечатление, будто вы пишете объектно-ориентированный код, а на самом деле это не так. Это просто зло.

1 голос
/ 31 января 2016

Здесь есть много хороших ответов, добавляя к этому,

Память: Статические переменные живут до тех пор, пока работает загрузчик классов [в общем, до тех пор, пока VM не умрет], но это только в случаемассовые объекты / ссылки хранятся как статические.

Модуляризация: рассмотрите такие понятия, как IOC, dependencyInjection, прокси и т. д. Все они полностью против тесно связанных / статических реализаций.

Другие доводы: безопасность потоков, тестируемость

0 голосов
/ 01 ноября 2018

С моей точки зрения, static переменная должна быть только только для чтения данные или переменные, созданные по соглашению .

Напримеру нас есть пользовательский интерфейс какого-то проекта, у нас есть список стран, языков, ролей пользователей и т. д. И у нас есть класс для организации этих данных.мы абсолютно уверены, что приложение не будет работать без этих списков.поэтому первое, что мы делаем в приложении init, это проверка этого списка на наличие обновлений и получение этого списка из API (при необходимости).Таким образом, мы согласны, что эти данные «всегда» присутствуют в приложении.Это практически данные только для чтения, поэтому нам не нужно заботиться о их состоянии - думая об этом случае, мы действительно не хотим иметь много экземпляров этих данных - этот случай выглядит идеальным кандидатом на статическая .

0 голосов
/ 11 октября 2017

Я думаю, что чрезмерное использование глобальных переменных со статическим ключевым словом также приведет к утечке памяти в какой-то момент в приложении

0 голосов
/ 07 августа 2015

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

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