Недавно я просматривал свои предупреждения в Eclipse и наткнулся на это:
Он выдаст предупреждение компилятору, если метод может быть объявлен как статический.
[править] Точная цитата в справке Eclipse, с акцентом на частные и окончательные:
При включении компилятор выдает ошибку или предупреждение для методов, которые являются закрытыми или окончательными и относятся только к статическим членам.
Да, я знаю, что могу его выключить, но я хочу знать причину включения?
Почему было бы хорошо объявить все возможные методы статическими?
Даст ли это какие-то преимущества в производительности? (в мобильном домене)
Указывая на метод как на статический, я полагаю, это показывает, что вы не используете никакие переменные экземпляра, поэтому их можно переместить в класс стиля utils?
В конце концов, следует ли мне просто отключить это «игнорирование» или исправить более 100 предупреждений, которые он мне выдал?
Вы думаете, что это просто лишние ключевые слова, которые загрязняют код, поскольку компилятор все равно просто встроит эти методы? (вроде как вы не объявляете каждую переменную, которую вы можете final, но вы могли бы ).
источник
Ответы:
Каждый раз, когда вы пишете метод, вы выполняете контракт в заданной области. Чем уже область видимости, тем меньше вероятность того, что вы напишете ошибку.
Когда метод является статическим, вы не можете получить доступ к нестатическим членам; следовательно, ваши возможности уже. Итак, если вам не нужны и никогда не понадобятся (даже в подклассах) нестатические члены для выполнения вашего контракта, зачем предоставлять доступ к этим полям вашему методу? Объявление метода
static
в этом случае позволит компилятору проверить, что вы не используете элементы, которые не собираетесь использовать.Более того, это поможет людям, читающим ваш код, понять природу контракта.
Вот почему считается хорошим объявить метод,
static
когда он фактически реализует статический контракт.В некоторых случаях ваш метод означает только что-то относительно экземпляра вашего класса, и бывает, что его реализация фактически не использует какое-либо нестатическое поле или экземпляр. В таких случаях вы не должны отмечать метод
static
.Примеры того, где вы не могли бы использовать
static
ключевое слово:источник
private
метод может быть объявлен статическим, то почти всегда так и должно быть. Для любого другого уровня доступа необходимо учитывать другие факторы, например динамическую отправку.object.method()
выделении метода для вызова.Здесь нет понятия оптимизации.
static
Метод ,static
потому что вы явно объявить , что метод не опирается на какой - либо , например ограничивающий класс только потому , что это не нужно. Итак, предупреждение Eclipse, как указано в документации:Если вам не нужна никакая переменная экземпляра и ваш метод является частным (не может быть вызван извне) или окончательным (не может быть переопределен), тогда нет причин, чтобы он был обычным методом, а не статическим. Статический метод по своей сути более безопасен даже потому, что вам разрешено делать с ним меньше действий (ему не нужен экземпляр, у вас нет неявного
this
объекта).источник
У меня нет информации о производительности, я полагаю, что это немного лучше, самое большее, поскольку код не должен выполнять динамическую отправку в зависимости от типа.
Однако гораздо более веским аргументом против рефакторинга статических методов является то, что в настоящее время использование static считается плохой практикой. Статические методы / переменные плохо интегрируются в объектно-ориентированный язык, а также их трудно правильно протестировать. Это причина, по которой некоторые новые языки вообще отказываются от концепции статических методов / переменных или пытаются интернализовать их в язык таким образом, который лучше подходит для объектно-ориентированного программирования (например, объекты в Scala).
В большинстве случаев вам нужны статические методы для реализации функций, которые используют только параметры в качестве входных данных и производят с их помощью выходные данные (например, служебные / вспомогательные функции). В современных языках существует концепция функций первого класса, которая позволяет это, поэтому статические не нужен. В Java 8 будут интегрированы лямбда-выражения, поэтому мы уже движемся в этом направлении.
источник
private static
методы, поэтому вам не придется издеваться над ними,1. Объявление метода
static
дает небольшое преимущество в производительности, но, что более полезно, позволяет использовать его, не имея под рукой экземпляра объекта (подумайте, например, о фабричном методе или получении синглтона). Он также служит документальной цели раскрытия сущности метода. Эту документальную цель не следует игнорировать, поскольку она дает немедленную подсказку о природе метода читателям кода и пользователям API, а также служит инструментом мышления для исходного программиста - явное указание предполагаемого значения помогает вы также мыслите правильно и производите более качественный код (я думаю, исходя из моего личного опыта, но люди разные). Например, логично и, следовательно, желательно проводить различие между методами, работающими с типом, и методами, действующими на экземпляр типа (как указано вДжон Скит в своем комментарии к вопросу о C # ).Еще один вариант использования
static
методов - имитировать интерфейс процедурного программирования. Подумайте оjava.lang.System.println()
классе, его методах и атрибутах. Классjava.lang.System
используется как пространство имен группировки, а не как экземпляр объекта.2. Как Eclipse (или любой другой запрограммированный или другой вид - биосовместимый или небиосоставный - объект) может точно знать, какой метод может быть объявлен как статический? Даже если базовый класс не обращается к переменным экземпляра или не вызывает нестатические методы, с помощью механизма наследования все может измениться. Только если метод не может быть переопределен путем наследования подкласса, мы можем утверждать со 100% уверенностью, что метод действительно может быть объявлен
static
. Переопределение метода невозможно точно в двух случаях:private
(ни один подкласс не может использовать его напрямую и даже в принципе не знает об этом), илиfinal
(даже если этот метод доступен подклассу, нет возможности изменить метод для ссылки на данные экземпляра или функции).Отсюда логика опции Eclipse.
3. На исходном плакате также спрашивается: « Указание метода как статического, я полагаю, показывает, что вы не используете никакие переменные экземпляра, поэтому их можно переместить в класс стиля utils? » Это очень хороший момент. Иногда на такое изменение дизайна указывает предупреждение.
Это очень полезная опция, которую я лично обязательно включил бы, если бы я использовал Eclipse и программировал на Java.
источник
См. Ответ Самуэля о том, как меняется объем метода. Думаю, это главный аспект создания статического метода.
Вы также спросили о производительности:
Прирост производительности может быть незначительным, поскольку для вызова статического метода не требуется неявная ссылка this в качестве параметра.
Однако это влияние на производительность действительно незначительно. Поэтому все дело в размахе.
источник
Из рекомендаций по производительности Android:
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
источник
Что ж, документация Eclipse говорит о рассматриваемом предупреждении:
Я думаю, этим все сказано. Если метод является частным и окончательным и относится только к статическим членам, рассматриваемый метод также может быть объявлен статическим и тем самым сделать очевидным, что мы намереваемся получить доступ только к статическому содержимому из него.
Честно говоря, я не думаю, что за этим стоит какая-то загадочная причина.
источник
Мне не хватало некоторых цифр для разницы в скорости. Поэтому я попытался протестировать их, но это оказалось не так просто: цикл Java становится медленнее после некоторых запусков / ошибки JIT?
Наконец, я использовал Caliper, и результаты такие же, как при выполнении моих тестов вручную:
Для статических / динамических вызовов нет ощутимой разницы. По крайней мере, не для Linux / AMD64 / Java7.
Результаты Caliper здесь: https://microbenchmarks.appspot.com/runs/1426eac9-36ca-48f0-980f-0106af064e8f#r:scenario.benchmarkSpec.methodName,scenario.vmSpec.options.CMSLargeCoalSurplusPercentm. CMSLargeSplitSurplusPercent, сценарий.vmSpec.options.CMSSmallCoalSurplusPercent, сценарий.vmSpec.options.CMSSmallSplitSurplusPercent, сценарий.vmSpec.options.FLSLargestBlockCoalesceProximitySpec.
и мои собственные результаты:
Класс Caliper Test был:
И мой собственный тестовый класс был:
источник
Методы, которые вы можете объявить как статические, не требуют создания экземпляров, например
Затем вы можете вызвать его в любом другом классе без создания экземпляра этого класса.
... Но это то, что вы, вероятно, уже знаете. Это не дает вам никаких реальных преимуществ, кроме как прояснить, что метод не использует никаких переменных экземпляра.
Другими словами, безопаснее всего его полностью отключить. Если вы знаете, что никогда не будете использовать метод в других классах (в этом случае он должен быть только частным), вам совсем не нужно, чтобы он был статическим.
источник