Java: когда использовать статические методы - PullRequest
835 голосов
/ 20 апреля 2010

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

* 1003 например *

Obj x = new Obj();
x.someMethod

или

Obj.someMethod

(это статический способ?)

Я довольно смущен!

Ответы [ 20 ]

1347 голосов
/ 20 апреля 2010

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

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

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

502 голосов
/ 15 марта 2011

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

  1. Если вы пишете служебные классы, и они не должны быть изменены.
  2. Если метод не использует никакую переменную экземпляра.
  3. Если какая-либо операция не зависит от создания экземпляра.
  4. Если есть некоторый код, который может быть легко использован всеми методами экземпляра, извлеките этот код в статический метод.
  5. Если вы уверены, что определение метода никогда не будет изменено или переопределено. Так как статические методы не могут быть переопределены.
162 голосов
/ 11 декабря 2013

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

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

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

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

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

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

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

39 голосов
/ 20 апреля 2010

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

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

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

Основная проблема со статическими методами - это процедурный код

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

31 голосов
/ 10 июня 2014

A 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.");
     }
  }
18 голосов
/ 20 апреля 2010

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

11 голосов
/ 13 июня 2015

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

  1. Статический метод принадлежит классу, а не объекту класса.
  2. Статический метод, вызываемый без необходимости создания экземпляра класса.
  3. Статический метод может обращаться к статическому члену данных и может изменять его значение.
  4. Доступ к статическому методу можно получить, просто используя имя статического имени точки класса. , , пример: Student9.change ();
  5. Если вы хотите использовать нестатические поля класса, вы должны использовать нестатический метод.

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

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

11 голосов
/ 20 апреля 2010

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

8 голосов
/ 20 апреля 2010

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

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

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

6 голосов
/ 25 апреля 2018

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

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

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

...