Чому існують приватні статичні методи?


68

Я просто хотів прояснити питання, яке у мене є. Який сенс мати приватний статичний метод на відміну від звичайного методу з приватною видимістю?

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

Єдина причина, про яку я можу подумати, - це те, що він допомагає концептуально зрозуміти метод на рівні класу на відміну від об'єктного рівня.


32
Так, є причина. Ваші загальнодоступні / за замовчуванням статичні методи все ще можуть викликати ваші приватні статики. Чи потрібно взагалі застосовувати статичні методи та коли доцільно використовувати приватні методи будь-якого типу, це окремі питання, тому будьте обережні, щоб не змішувати їх із цим питанням.

2
Швидкий приклад - заводський метод, який використовується внутрішнім класом, що запобігає виклику іншими класами (вам потрібно пройти заводський метод, щоб отримати екземпляр класу).

2
@MattFenwick: слід опублікувати це як відповідь.
Док Браун

9
Роблячи метод статичним, ви також говорите, що він не читає і не записує до змінних екземплярів. Метод, який не взаємодіє зі змінними екземплярів, часто легше переміщати та перетворювати в інші місця.
Марк Роджерс

1
Не забувайте, що незалежно від того, є статичний метод приватним, внутрішнім чи загальнодоступним, він все ще не є безпечним для потоків без конкретних зусиль синхронізації коду з вашого боку.
Крейг

Відповіді:


70

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

Причини, через які вам потрібно буде статичний метод (деякий код, який не залежить від нестатичних членів), все ще будуть корисні. Але, можливо, ви не хочете, щоб хтось / щось інше цим користувався, лише ваш клас.


3
Я думаю, що ви на правильному шляху, але я також думаю, що вам не вистачає ключового моменту. Більшість статичних методів мають нульові побічні ефекти (вони ефективно функціонують, а не методи) - саме тому вони робляться статичними в першу чергу. Аргумент проти їх приватності - "Якщо вони не мають побічних ефектів, чому б не зробити їх загальнодоступними для просування повторного використання коду". Це ключовий момент: коли ми робимо його приватним, це зазвичай тому, що ми хочемо, щоб ви повторно використовували весь клас, який використовує цей приватний метод, а не лише цей метод.
corsiKa

Треба сказати, що я ніколи цього не робив і не бачив. Кілька разів я це робив для допоміжних методів для публічних статичних класів.
Міямото Акіра

1
@corsiKa: Побічні ефекти - це не проблема. Якщо статичний член класу не приватний фактично, це обіцяє, що кожна майбутня версія класу буде включати той самий метод з тим самим іменем, який робить те саме. Якщо потреби змінюються, і в майбутній версії класу може не виникати потреби в методі, який працює точно так само, як і в поточному, приватний метод може бути сміливо замінений тим, який краще відповідає новим потребам класу. В якості простого прикладу припустимо, що клас необхідний метод , який приймає рядок і виконує заміни , як <в &lt;і т.д. Коли це написано ...
SUPERCAT

1
... Відомо, що рядки, які передаються, не містять розширень, і, таким чином, не перетворюються &на &amp;[як я писав код, я перетворив &би його, &amp;навіть якщо не очікував, що це буде необхідним, але припустимо це не так]. Це пізніше стає необхідним для обробки амперсандів, але цей метод є відкритим, змінюючи його розширити , &щоб &amp;можна було порушити зовнішній код , який виконує свою власну &-До- &amp;заміну. Якщо метод приватний, проте його можна буде виправити, &не створюючи проблем із зовнішнім кодом.
supercat

Це найменше цікава проблема, але я не бачу, як статичність робить її більше проблемою, ніж не статичною, що є ключовим у цьому питанні. Якщо ми будемо слідувати вашій логіці, все скрізь повторюватиме все, тому що "омг, що робити, коли колись помилка чи вимоги зміниться?"
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. не залежить від внутрішнього стану цього класу

12

Ви бачите, що у вас є кілька рядків коду, який повторюється у багатьох ваших методах, тому ви вирішили витягнути їх до одного методу, оскільки дубльований код не є корисним.

Ви робите метод приватним, оскільки він не розроблений для широкого використання, і ви не хочете пов'язаний з ним код. (Дебати з цього питання в коментарях…)

Оскільки метод не має доступу до будь-яких полів примірника, він може стати статичним, зробивши його статичним, ви полегшите розуміння і, можливо, навіть трохи швидше.

Потім .... (Може, зараз, може пізніше, може, ніколи)

Після того, як метод став статичним, зрозуміло, що його можна перемістити з класу, скажімо, до класу єдності.

Також легко перетворити його в метод екземпляра одного з його параметрів, часто саме тут має бути код.


Мені подобається ця відповідь, але чи є у вас актуальна посилання на це? "а може, навіть трохи швидше"
Magnilex

@Magnilex, Покажчик "цього" не передається методам статичного класу, тому вони, як правило, будуть швидшими, ніж методи статичного екземпляра, якщо компілятор не виявить, що "це" не використовується в методі екземпляра (малоймовірно).
Ян

2

Я можу придумати щонайменше дві причини, чому тобі потрібен статичний приватний метод на класі.

1: Ваші екземпляри мають підстави викликати статичний метод, який ви не хочете викликати безпосередньо, можливо тому, що він обмінюється даними між усіма примірниками вашого класу.

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

Звичайно, "це допомагає класу мати сенс" - це все-таки причина.


1

Як правило, якщо я виявляю, що пишу приватні статичні методи, я вважаю, що я мав би щось моделювати окремо.

Оскільки вони не прив’язані до стану конкретного екземпляра об'єкта, колекція публічних та приватних статичних методів може сформувати абсолютно окремий клас із власною семантикою та нестатичними методами.

(Ще одна порада - якщо я знайду, що у мене є багато статичних методів (державних та приватних), які мають загальний параметр якогось типу, вони можуть бути кращими як члени цього типу.)

Отже, щоб відповісти на ваше запитання, приватні статичні методи з’являються, коли клас надає групу споріднених методів, незалежних від екземпляра цього класу. (... а оскільки вони незалежні, їм може бути краще у власному класі.)


-1

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.