Когда мы должны использовать статическую карту? [Дубликат]

+ минимальна, * также может быть нулевой.

714
задан Community 5 April 2016 в 03:49
поделиться

21 ответ

Одно правило большого пальца: спросите себя: «Имеет ли смысл называть этот метод, даже если объект Obj еще не создан?» Если это так, это определенно будет статичным.

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

(Btw, обратное не всегда верно : иногда вы можете иметь метод, который включает в себя два объекта Car и все еще хочет, чтобы он был статичным. Например Car theMoreEfficientOf( Car c1, Car c2 ). Хотя это можно было бы преобразовать в нестатистическую версию, некоторые утверждают, что, поскольку нет «привилегированный» выбор того, какой автомобиль более важен, вы не должны заставлять вызывающего абонента выбирать один автомобиль как объект, на который вы будете ссылаться на этот метод. Однако эта ситуация составляет довольно небольшую часть всех статических методов.)

1179
ответ дан not-just-yeti 15 August 2018 в 20:52
поделиться
  • 1
    Несколько хороших примеров здесь. Я добавил бы, однако, что "статические" часто ценен, когда вы знаете, что что-то не изменится в разных случаях. Если это так, я бы действительно рассмотрел «Принцип единой ответственности», который подразумевает, что класс должен иметь одну ответственность и, следовательно, только одну причину изменения. Я считаю, что нужно переместить «ConvertMpgToKpl (double mpg)», функции и аналогичные методы для их собственного класса. Целью объекта автомобиля является создание экземпляров автомобилей, а не сравнение между ними. Они должны быть внешними по отношению к классу. – Zack Jannsen 13 August 2012 в 12:04
  • 2
    Думаю, я предпочел бы метод Car#isMoreEfficientThan(Car). Преимущество состоит в том, что автомобиль, который вы возвращаете в галстуке, не является произвольным. По названию метода очевидно, что возвращается в галстуке. – Cruncher 7 January 2014 в 16:03
  • 3
    Я также был бы осторожен в создании статического метода, который использует некоторый внешний ресурс (файловая система, база данных и т. Д.), Этот тип статики может сделать его ужасным для тестирования методов потребления. Я лично стараюсь сохранить статику в области «полезности». – Seth M. 7 April 2014 в 14:50
  • 4
    Фактически, он должен быть реализован как Comparator . – Dogweather 4 February 2015 в 00:36
  • 5
    @ B1KMusic Конечно. Что я подразумеваю под ", какой автомобиль возвращается в галстуке" является «истинными» картами к вызываемому на автомобиле и ложным картам к пройденному автомобилю ». Это без двусмысленности. – Cruncher 14 January 2016 в 21:28

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

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

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

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

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

37
ответ дан Alfred 15 August 2018 в 20:52
поделиться
  • 1
    Я не понимаю, что касается того, что вы не можете выполнять процедурный код unit-test. Разве вы не просто настраиваете тестовые примеры, которые отображают правильный ввод для правильного вывода, используя статический метод вместе с классом как ваш «блок» ?? – tjb 21 March 2012 в 20:40
  • 2
    Вы можете сделать это, чтобы проверить эти функции. Но при использовании этих статических методов в других классах, которые вы хотите протестировать, я считаю, что вы не можете их подделывать (mocks / friendlies) или что-то еще, потому что вы не можете создать экземпляр класса. – Alfred 22 March 2012 в 01:01
  • 3
    @Alfred: Посмотрите на PowerMock , который имеет возможность издеваться над статическими методами. При использовании PowerMock существует несколько сценариев, если они есть, где вы найдете зависимости методов, которые не могут быть издевательскими. – Carles Sala 20 May 2013 в 17:33
  • 4
    Вы можете тестировать статику с помощью PowerMock, однако вскоре вы обнаружите, что у вас закончилось пространство Перменгена (сделано, получилось футболка), и все еще противно. Если вы НЕ ЗНАЕТЕ (основанный, по крайней мере, на десять лет вашего собственного опыта в реальных языках OO, не переносясь с C), тогда НЕ ДЕЛАЙТЕ ЭТО. Серьезно, худший код, который я когда-либо видел, исходил от использования статикой встроенного разработчика, и в большинстве случаев мы застряли на нем, навсегда, и добавление большего количества кода просто еще более заперло нас в немодифицируемом монолите. Свободная муфта: нет, проверяемая: едва модифицируется: НИКОГДА. Избегайте! – user1016765 26 May 2014 в 19:12
  • 5
    Я могу понять сложность тестирования статических методов, которые зависят от статического состояния. Но когда вы тестируете статические методы stateless , такие как Math.abs() или Arrays.sort(), даже методы, которые вы можете передать все зависимости в , я не вижу, как это будет когда-либо препятствовать единичному тестированию. Я бы сказал, что простое эмпирическое правило: если у вас когда-либо возникнет какая-либо причина издеваться над процедурной логикой, то не ставьте ее статическим методом. У меня никогда не было причин издеваться над Arrays.sort() или Math.abs(). – Andy 8 May 2015 в 20:24

Статические методы могут использоваться, если

  • Не нужно выполнять действие над экземпляром (методы утилиты). Как упоминалось в нескольких из приведенных выше ответов в этом сообщении, преобразование миль в километры, или расчета температуры от Фаренгейта до Цельсия и наоборот. В этих примерах с использованием статического метода ему не нужно создавать экземпляр целого нового объекта в кучевой памяти. Рассмотрим ниже
    1. new ABCClass(double farenheit).convertFarenheitToCelcium() 
    2. ABCClass.convertFarenheitToCelcium(double farenheit)
    
    , первый создает новый класс для каждого метода invoke, Performance, Practical . Примерами являются класс Math и Apache-Commons StringUtils ниже:
    Math.random()
    Math.sqrt(double)
    Math.min(int, int)
    StringUtils.isEmpty(String)
    StringUtils.isBlank(String)
    
  • Один хочет использовать как простую функцию. Входы явно передаются и получают данные результата в качестве возвращаемого значения. Наследование, объектная инсталляция не возникает. Краткая, читаемая .

ПРИМЕЧАНИЕ. Немногие люди возражают против проверки статических методов, но статические методы также могут быть протестированы! С помощью jMockit можно издеваться над статическими методами. Тестируемость . Пример ниже:

new MockUp<ClassName>() {
    @Mock
    public int doSomething(Input input1, Input input2){
        return returnValue;
    }
};
3
ответ дан Amit Kaneria 15 August 2018 в 20:52
поделиться

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

Вы использовали бы статический метод, если метод не использует никаких полей (или только статических полей) класса.

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

6
ответ дан Carsten 15 August 2018 в 20:52
поделиться

Статические методы следует вызывать в классе, методы экземпляра следует вызывать в экземплярах класса. Но что это значит на самом деле? Вот полезный пример:

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

Класс автомобиля может также иметь метод подсчета с именем GetCarCount (). Это вернет общее количество созданных (или построенных) автомобилей. Если никакие автомобили не были построены, этот метод вернет 0, но он все равно должен быть вызван, и поэтому он должен быть статическим методом.

0
ответ дан Charlie Seligman 15 August 2018 в 20:52
поделиться

Нет, статические методы не связаны с экземпляром; они принадлежат классу. Статические методы - ваш второй пример; методы экземпляра являются первыми.

10
ответ дан duffymo 15 August 2018 в 20:52
поделиться

Статические методы и переменные - это управляемая версия функций и переменных «Глобальная» в Java. В каких методах можно получить доступ как classname.methodName() или classInstanceName.methodName(), то есть могут быть доступны статические методы и переменные, используя имя класса, а также экземпляры класса.

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

4
ответ дан Echilon 15 August 2018 в 20:52
поделиться

Static: Obj.someMethod

Используйте static, если вы хотите предоставить доступ к классу на уровне класса, то есть где метод должен быть доступен для вызова без экземпляра класса.

3
ответ дан Finbarr 15 August 2018 в 20:52
поделиться

Статический метод имеет две основные цели:

  1. Для служебных или вспомогательных методов, которые не требуют какого-либо состояния объекта. Поскольку нет необходимости обращаться к переменным экземпляра, статические методы устраняют необходимость того, чтобы вызывающий объект создавал экземпляр объекта только для вызова метода.
  2. Для состояния, которое используется всеми экземплярами класса, например счетчиком. Все экземпляры должны иметь одно и то же состояние. Методы, которые просто используют это состояние, также должны быть статическими.
0
ответ дан hemanto 15 August 2018 в 20:52
поделиться

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

Если применяются следующие условия, сделайте свой метод статическим:

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

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

Для получения дополнительной информации проверьте: Статическое ключевое слово в java

0
ответ дан Hussein Terek 15 August 2018 в 20:52
поделиться

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

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

// Программа изменения общего свойства всех объектов (статическое поле).

class Student9{  
 int rollno;  
 String name;  
 static String college = "ITS";  

 static void change(){  
 college = "BBDIT";  
 }  

 Student9(int r, String n){  
 rollno = r;  
 name = n;  
 }  

 void display (){System.out.println(rollno+" "+name+" "+college);}  

public static void main(String args[]){  
Student9.change();  

Student9 s1 = new Student9 (111,"Indian");  
Student9 s2 = new Student9 (222,"American");  
Student9 s3 = new Student9 (333,"China");  

s1.display();  
s2.display();  
s3.display();  
}  }

O / P: 111 Индийский BBDIT 222 Американский BBDIT 333 Китай BBDIT

9
ответ дан IndianProgrammer1234 15 August 2018 в 20:52
поделиться

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

4
ответ дан Jamey 15 August 2018 в 20:52
поделиться
  • 1
    Это не дает никакого обоснования для разработки программы. – adamjmarkham 1 January 2012 в 21:20

Метод static - это один тип метода, который не требует инициализации объекта для его вызова. Вы заметили, что static используется в функции main в Java? Выполнение программы начинается оттуда без создания объекта.

Рассмотрим следующий пример:

 class Languages 
 {
     public static void main(String[] args) 
     {
         display();
     }

     static void display() 
     {
         System.out.println("Java is my favorite programming language.");
     }
  }
26
ответ дан Jonah 15 August 2018 в 20:52
поделиться

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

15
ответ дан Kevin Sylvestre 15 August 2018 в 20:52
поделиться

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

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

3
ответ дан rashedcs 15 August 2018 в 20:52
поделиться

Мне интересно, когда использовать статические методы?

  1. Общим методом использования для static методов является доступ к полям static.
  2. Но вы можете иметь методы static, не ссылаясь на переменные static. Вспомогательные методы без ссылки на переменную static можно найти в некоторых Java-классах, таких как java.lang.Math
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
    
  3. В другом случае использования, я могу думать об этих методах вместе с synchronized метод - это реализация блокировки уровня класса в многопоточной среде.

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

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

Документация Oracle страница содержит более подробную информацию.

Не все комбинации переменных и методов экземпляра и класса разрешены:

  1. Методы экземпляров могут напрямую обращаться к переменным экземпляра и методам экземпляра.
  2. Методы экземпляра могут напрямую обращаться к переменным класса и методам класса.
  3. Методы класса могут напрямую обращаться к переменным класса и методам класса.
  4. Методы класса не могут напрямую обращаться к переменным экземпляра или методам экземпляра - они должны использовать объект Справка. Кроме того, методы класса не могут использовать это ключевое слово, поскольку для этого не существует экземпляра.
1
ответ дан Ravindra babu 15 August 2018 в 20:52
поделиться

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

6
ответ дан Sagar 15 August 2018 в 20:52
поделиться

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

  1. Если вы пишете классы утилит, и они не должны быть изменены.
  2. Если этот метод не используется любая переменная экземпляра.
  3. Если какая-либо операция не зависит от создания экземпляра.
  4. Если есть какой-то код, который может быть легко разделен всеми методами экземпляра, извлеките этот код в статический метод.
  5. Если вы уверены, что определение метода никогда не будет быть изменен или переопределен. Поскольку статические методы не могут быть переопределены.
461
ответ дан Simon Forsberg 15 August 2018 в 20:52
поделиться
  • 1
    Хорошие моменты, но они являются требованиями, если вы хотите сделать метод статическим, а не причины его создания. – tetsuo 11 December 2013 в 16:17
  • 2
    @Mohd о требовании 5: Когда вы можете быть на 100% уверены, что метод никогда не будет изменен или переопределен? Не всегда ли неизвестны факторы, которые вы не можете принять во внимание в момент написания своего статического метода? – PixelPlex 31 August 2015 в 12:03
  • 3
    & Quot; Utility-классы & Quot; очень трудно понять, плохо то, что рано или поздно все начинает выглядеть «полезной» (да, я имею в виду пакет «util», который раздувается, неприкасается и плохо тестируется), и ваши тестовые примеры потребуется больше работы (для издевательства статических utils HARD). Сначала выберите объекты. – Sergio 15 June 2016 в 08:00
  • 4
    @Mohd, этот ответ именно то, что я ищу. Я столкнулся с множеством проблем с использованием статических методов в многопоточности. Можете ли вы рассказать о точках 2, 3 больше (например, 100 палец вверх для вас) – Prakash Pandey 17 December 2016 в 18:24
  • 5
    Я думаю, что «статический класс» следует изобрести, если вы собираетесь использовать статические переменные и методы. – Robert Rocha 26 February 2018 в 15:08

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

  • Производительность: если вы хотите, чтобы какой-то код запускался, и вы не хотите создавать экземпляр дополнительного объекта, сделайте это в статический метод. JVM также может много оптимизировать статические методы (я думаю, что однажды я прочитал Джеймса Гослинга, заявив, что вам не нужны специальные инструкции в JVM, поскольку статические методы будут такими же быстрыми, но не могут найти источник - таким образом это может быть полностью ложным). Да, это микро-оптимизация и, вероятно, ненужная.
  • Практичность: вместо вызова new Util().method(arg) вызовите Util.method(arg) или method(arg) со статическим импортом.
  • Добавление методов: вы действительно хотели, чтобы класс String имел метод экземпляра removeSpecialChars(), но его нет (и этого не должно быть, так как специальные символы вашего проекта могут отличаться от другой проект), и вы не можете его добавить (поскольку Java является довольно разумным), поэтому вы создаете класс утилиты и вызываете removeSpecialChars(s) вместо s.removeSpecialChars(). Sweet.
  • Purity: принимая некоторые меры предосторожности, ваш статический метод будет чистой функцией , то есть единственное, от чего он зависит, - это его параметры. Данные, данные. Это легче читать и отлаживать, так как у вас нет наследования для наследования, о которых нужно беспокоиться. Вы можете сделать это также с помощью методов экземпляра, но компилятор поможет вам немного больше со статическими методами (не позволяя ссылаться на атрибуты экземпляра, переопределять методы и т. Д.).

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

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

139
ответ дан tetsuo 15 August 2018 в 20:52
поделиться
  • 1
    Много хороших причин, перечисленных здесь, когда статические могут быть полезны. Еще один, о котором я могу думать, - это то, что написание единичных тестов для таких методов просто прост – nilesh 24 July 2016 в 22:08
  • 2
    @tetsuo Спасибо! Ваше объяснение очень ясное, и приведенные причины очень логичны и имеют большой смысл. – Deniss M. 9 May 2017 в 07:48
  • 3
    И мы, программисты, никогда не делаем ненужных вещей только потому, что они классные, не так ли? +1 – Scaramouche 7 March 2018 в 17:54
  • 4
    Тем не менее статический метод становится полной именованной функцией stackoverflow.com/questions/155609/… – Ivanzinho 12 July 2018 в 23:53

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

1
ответ дан user489872 15 August 2018 в 20:52
поделиться

Статические методы не должны вызываться на объекте, и это когда вы его используете. Пример: ваш Main () является статичным, и вы не создаете объект для его вызова.

3
ответ дан Vaishak Suresh 15 August 2018 в 20:52
поделиться
  • 1
    Ура! Посмотрите, где я пришел, когда вы писали вопросы Java noobie! Это маленький мир :-) – Deepak 5 November 2015 в 10:07
  • 2
    @Deepak маленький мир действительно :) – Vaishak Suresh 9 November 2015 в 21:49
Другие вопросы по тегам:

Похожие вопросы: