Вопрос-ответ

When to use static methods

Когда использовать статические методы

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

Пример:

Obj x = new Obj();
x.someMethod();

...или:

Obj.someMethod(); // Is this the static way?

Я в замешательстве!

Переведено автоматически
Ответ 1

Одно практическое правило: спросите себя: "Имеет ли смысл вызывать этот метод, даже если объект еще не создан?" Если да, то он определенно должен быть статическим.

Итак, в классе Car у вас может быть метод:

double convertMpgToKpl(double mpg)

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

void setMileage(double mpg)

...не может быть статическим, поскольку немыслимо вызвать метод до того, как какой-либо Car был создан.

(Кстати, обратное не всегда верно: иногда у вас может быть метод, который включает два Car объекта, и вы все равно хотите, чтобы он был статическим. Например.:

Car theMoreEfficientOf(Car c1, Car c2)

Хотя это можно было бы преобразовать в нестатическую версию, некоторые утверждают, что, поскольку нет "привилегированного" выбора того, что Car важнее, вы не должны заставлять вызывающую программу выбирать один из них Car в качестве объекта, для которого вы будете вызывать метод. Однако на эту ситуацию приходится довольно небольшая доля всех статических методов.

Ответ 2

Определяйте статические методы только в следующих сценариях:


  1. Если вы пишете служебные классы и их не предполагается изменять.

  2. Если метод не использует какую-либо переменную экземпляра.

  3. Если какая-либо операция не зависит от создания экземпляра.

  4. Если есть какой-то код, который может быть легко общим для всех методов экземпляра, извлеките этот код в статический метод.

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

Ответ 3

Есть несколько веских причин для использования статических методов:


  • Производительность: если вы хотите запустить какой-то код и не хотите создавать для этого экземпляр дополнительного объекта, поместите его в статический метод. JVM также может значительно оптимизировать статические методы (кажется, я когда-то читал заявление Джеймса Гослинга о том, что вам не нужны пользовательские инструкции в JVM, поскольку статические методы будут такими же быстрыми, но не смог найти источник - таким образом, это может быть полностью ложным). Да, это микрооптимизация, и, вероятно, ненужная. И мы, программисты, никогда не делаем ненужных вещей только потому, что они классные, верно?


  • Практичность: вместо вызова new Util().method(arg) вызывайте Util.method(arg) или method(arg) со статическим импортом. Проще, короче.


  • Добавление методов: вы действительно хотели, чтобы в строке класса был removeSpecialChars() метод экземпляра, но его там нет (и не должно быть, поскольку специальные символы вашего проекта могут отличаться от символов другого проекта), и вы не можете его добавить (поскольку Java несколько вменяем), поэтому вы создаете служебный класс и вызываете removeSpecialChars(s) вместо s.removeSpecialChars(). Сладко.


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


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

Теперь, что более важно, почему вы не хотели бы создавать статический метод? По сути, полиморфизм выходит за рамки. Вы не сможете переопределить этот метод, ни объявлять это в интерфейсе (до Java 8). Это требует от вашего дизайна большой гибкости. Кроме того, если вам нужно состояние, вы в конечном итоге столкнетесь с множеством ошибок параллелизма и / или узких мест, если не будете осторожны.

Ответ 4

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

как мне убедиться, что у меня есть только один из них


есть только одно из чего-то Проблема “как мне убедиться, что у меня есть только одно из чего-то”, удачно обойдена стороной. Вы создаете экземпляр только одного ApplicationFactory в вашем main, и в результате вы создаете только один экземпляр всех ваших singletons.


Основная проблема со статическими методами заключается в том, что они являются процедурным кодом


Основная проблема со статическими методами заключается в том, что они представляют собой процедурный код. Я понятия не имею, как модульно тестировать процедурный код. Модульное тестирование предполагает, что я могу создать экземпляр части моего приложения изолированно. Во время создания экземпляра я подключаю зависимости с помощью mocks / friendlies, которые заменяют реальные зависимости. При процедурном программировании "подключать" нечего, поскольку объектов нет, код и данные разделены.


java