Почему есть частные статические методы?

68

Я просто хотел прояснить вопрос, который у меня есть. Какой смысл иметь приватный статический метод в отличие от обычного метода с приватной видимостью?

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

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

Рехан Накви
источник
32
Да, есть причина. Ваши публичные / стандартные статические методы могут по-прежнему вызывать вашу частную статику. Вопрос о том, следует ли вообще использовать статические методы и когда уместно использовать частные методы любого рода, это отдельные вопросы, поэтому будьте осторожны, чтобы не смешивать их с этим вопросом.
2
Быстрый пример - фабричный метод, используемый внутренним классом, предотвращающий вызовы другими классами (вам нужно пройти через фабричный метод, чтобы получить экземпляр класса).
2
@MattFenwick: вы должны опубликовать это как ответ.
Док Браун
9
Делая метод статичным, вы также говорите, что он не читает и не записывает переменные экземпляра. Метод, который не взаимодействует с переменными экземпляра, часто проще переместить и изменить в других местах.
Марк Роджерс
1
Не забывайте, что независимо от того, является ли статический метод закрытым, внутренним или общедоступным, он по-прежнему не является поточно-ориентированным без особых усилий по синхронизации кода с вашей стороны.
Крейг

Ответы:

70

Характеристика статичности не зависит от видимости.

Причины, по которым вы захотите использовать статический метод (некоторый код, который не зависит от нестатических элементов), все равно будут полезны. Но, может быть, вы не хотите, чтобы кто-то / что-либо еще использовал это, только ваш класс.

Миямото Акира
источник
3
Я думаю, что вы на правильном пути, но я также думаю, что вы упускаете ключевой момент. Большинство статических методов имеют нулевые побочные эффекты (это, по сути, функции, а не методы) - поэтому они изначально сделаны статичными. Аргумент против их приватности гласит: «Если у них нет побочных эффектов, почему бы не сделать их открытыми для повторного использования кода». Это ключевой момент: когда мы делаем его закрытым, обычно это потому, что мы хотим, чтобы вы повторно использовали весь класс, который использует этот закрытый метод, а не только этот метод.
CorsiKa
Я должен сказать, что никогда не делал этого и не видел такого поведения. Несколько раз я делал это для вспомогательных методов для открытых статических классов.
Миямото Акира
1
@corsiKa: побочные эффекты не проблема. Создание статического члена класса не закрытым эффективно обещает, что каждая будущая версия класса будет включать в себя один и тот же метод с тем же именем, который делает то же самое. Если потребности изменятся, и будущая версия класса может не нуждаться в методе, который работает точно так же, как текущий, частный метод можно смело заменить на метод, который лучше удовлетворяет новым потребностям класса. В качестве простого примера предположим, что класс необходим метод , который принимает строку и выполняет замены , как <в &lt;и т.д. Когда это написано ...
SUPERCAT
1
... строки , которые оно прошло , как известно , не содержат каких - либо амперсандов, и , таким образом , не конвертируется &в &amp;[были я пишу код, я бы преобразовать &в &amp;даже если я не ожидал , что это будет необходимо, но предположим , что это не]. Это позже становится необходимым для обработки амперсандов, но этот метод является открытым, изменяя его расширить , &чтобы &amp;можно было нарушить внешний код , который выполняет свою собственную &-До- &amp;замену. Однако, если метод является закрытым, его можно исправить, чтобы он &не вызывал проблем для какого-либо внешнего кода.
суперкат
Это интересная проблема, мягко говоря, но я не вижу , как это статичность делает любой более проблему , чем не является статичным, который является ключом к этому вопросу. Если мы будем следовать вашей логике, все везде будет переопределять все, потому что "Боже, что, если есть ошибка или требования когда-нибудь изменятся?"
CorsiKa
26

Довольно распространенной причиной (в Java) будет инициализация неизменяемых переменных поля в конструкторе с помощью простого private staticметода для уменьшения беспорядка в конструкторе.

  • Это private: внешние классы не должны видеть это.
  • Это static: он может выполнять некоторые операции, независимые 1 из состояния класса хозяина.

Несколько надуманный пример следует ...

например:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 Предполагая, что он не взаимодействует с другими staticпеременными.

Шелдон Варкентин
источник
15
Это еще более ценно, когда вам нужно передать производные (вычисляемые) аргументы в конструктор суперкласса. super(...)Вызов должен быть в первой строке вашего класса конструктор, так что вы не можете объявлять локальные переменные , чтобы помочь вам разобраться , что перейти на супер вызов. Тем не менее, вы можете вызывать (приватные) статические методы, которые используют столько строк, сколько необходимо для определения значения, передаваемого суперструктору.
Анджей Дойл
обратите внимание, что есть возможность статического блока инициализации
Франц Эбнер
13

Распространенным вариантом использования private staticметода является служебный метод, который

  1. используется только этим одним классом
  2. не зависит от внутреннего состояния этого класса
Philipp
источник
12

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

Вы делаете метод закрытым, поскольку он не предназначен для широкого использования, и вы не хотите, чтобы его вызывал несвязанный код. (Обсудите этот момент в комментариях….)

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

Тогда .... (Может быть, сейчас, может позже, может быть, никогда)

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

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

Ян
источник
Мне нравится этот ответ, но есть ли у вас актуальная ссылка для этого? «а может быть, даже немного быстрее»
Magnilex,
@Magnilex, указатель «this» не передается статическим методам класса, поэтому они будут быстрее, чем статические методы экземпляра, если только компилятор не обнаружит, что «this» не используется в методе экземпляра (маловероятно).
Ян
2

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

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

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

Конечно, «это помогает классу обрести смысл» - хорошая причина сама по себе.

DougM
источник
1

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

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

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

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

обкрадывать
источник
-1

Очень простой пример, который я могу придумать, если вы хотите выполнить некоторую обработку входных аргументов (или некоторые манипуляции), которые передаются основной функции. Таким образом, в этом случае, если обработка большая и такая же функциональность не будет использоваться где-либо еще, имеет смысл иметь закрытую функцию, так как она не будет использоваться / вызываться откуда-либо еще + static, поскольку main является статическим.

techExplorer
источник