Одно правило большого пальца: спросите себя «имеет ли смысл называть этот метод, даже если объект Obj еще не построен?» Если это так, это обязательно должно быть статичным.
Так что в классе Car
у вас может быть метод double convertMpgToKpl(double mpg)
, который был бы статическим, потому что можно было бы узнать, к чему преобразуется 35mpg, даже если никто никогда не строил автомобиль. Но void setMileage(double mpg)
(который устанавливает эффективность одного конкретного автомобиля) не может быть статичным, поскольку невозможно вызвать метод до того, как какой-либо автомобиль будет построен.
(Btw, обратное не всегда верно: иногда вы можете иметь метод, который включает в себя два объекта Car, и все еще хочет, чтобы он был статичным. Например, Car theMoreEfficientOf(Car c1, Car c2)
.Хотя это можно было бы преобразовать в нестатистическую версию, некоторые утверждают, что, поскольку нет «привилегированного» выбора того, какой автомобиль более важен, вы не должны заставлять вызывающего абонента выбирать один автомобиль как объект, на который вы будете ссылаться. Эта ситуация объясняет довольно небольшую доля всех статических методов, хотя)
хотя есть некоторые веские причины, чтобы использовать статические методы:.
Производительность: если вы хотите, чтобы какой-то код запускался и не хотите создавать экземпляр дополнительного объекта, сделайте это в статическом методе. JVM также может много оптимизировать статические методы (я думаю, что однажды я прочитал Джеймса Гослинга, заявив, что вам не нужны специальные инструкции в JVM, поскольку статические методы будут такими же быстрыми, но не могут найти источник - таким образом это может быть полностью ложным). Да, это микро-оптимизация и, вероятно, ненужная. И мы, программисты, никогда не делаем ненужных вещей только потому, что они классные, не так ли?
Практичность: вместо вызова нового метода Util(). (Arg) вызовите метод Util.method (arg) или метод (arg) со статическим импортом. Легче, короче.
методы Добавление: вы действительно хотели класса String, чтобы иметь removeSpecialChars() метод экземпляра, но это не есть (и это не должно, так как специальные символы вашего проекта может отличаться от другого проекта), и вы не можете добавить его (поскольку Java минимально нормальная), поэтому вы создаете класс утилиты и вызываете removeSpecialChars (s) вместо s.removeSpecialChars(). Милая.
Purity: принимая некоторые меры предосторожности, ваш статический метод будет чистой функцией, то есть единственной вещью, от которой она зависит, являются ее параметры.Данные, данные. Это легче читать и отлаживать, так как у вас нет наследования для наследования, о которых нужно беспокоиться. Вы можете сделать это также с помощью методов экземпляра, но компилятор поможет вам немного больше со статическими методами (не позволяя ссылаться на атрибуты экземпляра, переопределять методы и т. Д.).
Вы также должны создать статический метод, если вы хотите сделать одноплодной, но ... нет. Я имею в виду, подумайте дважды.
Теперь, что более важно, почему вы не хотите создавать статический метод? В основном, полиморфизм выходит из окна. Вы не сможете переопределить метод и не объявлять его в интерфейсе. Это требует большой гибкости от вашего дизайна. Кроме того, если вам нужно состояние, вы получите множество ошибок ошибок параллелизма и/или узких мест, если вы не будете осторожны.
Так определить статические методы только в следующих случаях:
- Если вы пишете вспомогательные классы, и они не должны быть изменены.
- Если метод не использует переменную экземпляра.
- Если какая-либо операция не зависит от создания экземпляра.
- Если есть код, который может быть легко разделен всеми методами экземпляра, извлеките этот код в статический метод.
- Если вы уверены, что определение метода никогда не будет изменено или переопределено. Поскольку статические методы нельзя переопределить.
Позволяет также обсудить его более подробно:
Преимущества:
Статические члены/методы используются как в вспомогательных классов говорят как Math или в классах констант. который помогает другим объектам использовать строки или полезные функции, для которых вам не нужно создавать объект, но вызывается с использованием имени класса. Пример. Объекты singleton вызываются с использованием статической функции.
Недостатки:
Статические члены являются частью класса и, таким образом, остаются в памяти до Завершает приложения и не может быть когда-либо мусора. Использование избытка статических элементов когда-либо предсказывает, что вы не можете спроектировать свой продукт и пытаетесь использовать статическое/процедурное программирование. Это означает, что объектно-ориентированный дизайн скомпрометирован. Это может привести к переполнению памяти. Также есть некоторые недостатки, если вы ставите какой-либо метод статическим в Java, например, вы не можете переопределить какой-либо статический метод в Java, поэтому он усложняет тестирование, вы не можете заменить этот метод макетом. Поскольку статический метод поддерживает глобальное состояние, он может создавать тонкую ошибку в параллельной среде, которую трудно обнаружить и исправить.
Что нужно помнить:
Статическая переменная будет частью определения класса, а не в куче. Однако статические переменные полезны, когда вы знаете, что будут доступны объекты из нескольких мест. Доступ к статическим ресурсам не является потокобезопасным.Вы можете получить странные/непредсказуемые результаты в поточной среде. Но если ваше единственное чтение статического значения, то использование потоков для него в порядке.
Как Статическая Перерывы инкапсуляция:
техническая реализация которых должна позволить государству поддерживать во всех экземпляров класса. Проблема в том, что это по сути не ООП, поскольку она не учитывает инкапсуляцию. Если переменная может быть изменена любым экземпляром класса, то основной принцип скрытия инкапсуляции/информации полностью теряется: объект больше не полностью контролирует его состояние. Его состояние теперь зависит от переменных, которые по сути являются глобальными. Мы знаем, что это плохо. Даже частные статические переменные сохраняют состояние на глобальном уровне, но просто ограничивают его доступ. Любой экземпляр объекта может изменять статическую переменную, которая вызывает неоднозначность, поскольку отдельные экземпляры объекта больше не имеют контроля над своим собственным состоянием. Изменения состояния могут произвольно происходить без знания объекта, который полагается на это состояние, которое является проблематичным, потому что объект может работать неправильно, когда это происходит. Как часто говорят, что «Наследование прерывает инкапсуляцию», статика делает это гораздо более серьезным образом: не только подвергая внутреннюю реализацию, но и подвергая внутреннее состояние.
В вашем примере Вопрос:
Как упоминалось выше, метод будет использоваться в многопоточном invironment, думать о следующей задаче (модифицированный код):
public Object findTheCar(String id) {
Car car = null; //Line 2
if (id != null) {
car = new Car();
}
//Line 6
// do something
//
//Line 10
return car;
}
В приведенном выше примере: если это выполнено из двух потоков, а 1-я нить - на линии , а вторая нить находится в строке 2, все еще это w плохой нить безопасный.
Потому что:
Локальные переменные хранятся в собственном стеке каждого потока. Это означает, что локальные переменные никогда не разделяются между потоками. Это также означает, что все локальные примитивные переменные являются потокобезопасными.
Локальные ссылки на объекты немного разные. Сама ссылка не разделяется. Однако указанный объект не сохраняется в локальном стеке каждого потока. Все объекты хранятся в общей куче. Если объект, созданный локально, никогда не ускользает от метода, в котором он был создан, он является потокобезопасным. Фактически вы также можете передать его другим методам и объектам, если ни один из этих методов или объектов не передаст переданный объект другим потокам.
Элементы объекта хранятся в куче вместе с объектом. Поэтому, если два потока вызывают метод в одном экземпляре объекта, и этот метод обновляет члены объекта, этот метод не является потокобезопасным.
Проверка безопасности резьбы: если ресурс создан, используется и размещен внутри элемента управления одним и тем же потоком и никогда не избегает управления этим потоком, использование этого ресурса является потокобезопасным.
От: http://tutorials.jenkov.com/java-concurrency/thread-safety.html
Если вы обнаружите, что хотите писать классы, содержащие много/все статические методы, вы не думаете объектно-ориентированные; вы не делаете дизайн OO. Для получения дополнительной информации обратитесь к учебнику, например http://www.amazon.com/dp/0672330164/?tag=stackoverfl08-20. – BadZen
О, я не знаю, может быть, ваш работодатель, профессор, коллеги, будущий я и Будда? – BadZen
@BadZen некоторые из них кажутся действительными;) –