Perché avere metodi statici privati?


68

Volevo solo chiarire una domanda che ho. Qual è il punto di avere un metodo statico privato rispetto a un metodo normale con visibilità privata?

Avrei pensato che il vantaggio di avere un metodo statico è che può essere chiamato senza un'istanza di una classe, ma dal momento che il suo privato ha anche un punto per essere statico?

L'unica ragione a cui riesco a pensare è che aiuta a comprendere concettualmente il metodo a livello di classe anziché a livello di oggetto.


32
Sì, c'è un motivo. I tuoi metodi statici pubblici / predefiniti possono comunque chiamare le tue statiche private. Se i metodi statici debbano essere usati affatto e quando è appropriato usare metodi privati ​​di qualsiasi tipo, sono domande separate, quindi fai attenzione a non mescolarle con questa domanda.

2
Esempio rapido: metodo factory utilizzato da una classe interna che impedisce l'invocazione da parte di altre classi (è necessario passare attraverso il metodo factory per ottenere un'istanza della classe).

2
@MattFenwick: dovresti pubblicare questo come risposta.
Doc Brown,

9
Rendendo statico un metodo, stai anche dicendo che non legge o scrive nelle variabili di istanza. Un metodo che non interagisce con le variabili di istanza è spesso più facile da spostare e rifattorizzare in altri luoghi.
Mark Rogers,

1
Non dimenticare che indipendentemente dal fatto che un metodo statico sia privato, interno o pubblico, non è ancora sicuro per i thread senza uno sforzo di sincronizzazione del codice specifico da parte tua.
Craig

Risposte:


70

La caratteristica di essere statico è indipendente dalla visibilità.

I motivi per cui si desidera disporre di un metodo statico (del codice che non dipende da membri non statici) saranno comunque utili. Ma forse non vuoi che nessuno / qualcos'altro lo usi, solo la tua classe.


3
Penso che tu sia sulla buona strada, ma penso anche che ti manchi un punto chiave. La maggior parte dei metodi statici ha zero effetti collaterali (sono effettivamente funzioni, non metodi) - ecco perché sono stati resi statici in primo luogo. L'argomento contro cui sono privati ​​è "Se non hanno effetti collaterali, perché non renderli pubblici per promuovere il riutilizzo del codice". Questo è il punto chiave: quando lo rendiamo privato, di solito è perché vogliamo che riutilizzi l'intera classe che utilizza quel metodo privato, non solo quel metodo.
corsiKa

Devo dire che non l'ho mai fatto o visto quel comportamento. Le poche volte che l'ho fatto è stato per i metodi di supporto alle classi statiche pubbliche.
Miyamoto Akira,

1
@corsiKa: gli effetti collaterali non sono il problema. Rendere un membro statico di una classe non privata promette efficacemente che ogni futura versione di una classe includerà lo stesso metodo con lo stesso nome che fa la stessa cosa. Se le esigenze cambiano, e una versione futura della classe potrebbe non aver bisogno di un metodo che funzioni esattamente come quello attuale, un metodo privato può essere tranquillamente sostituito con uno che soddisfi meglio le nuove esigenze della classe. Come semplice esempio, si supponga che una classe bisogno di un metodo che prende una stringa ed esegue sostituzioni come <a &lt;, ecc Quando è scritto ...
Supercat

1
... le corde cui viene passato sono noti non contengono e commerciali, e quindi non converte &a &amp;[erano ho la scrittura del codice, mi piacerebbe convertire &a &amp;anche se non mi aspettavo che fosse necessario, ma supponiamo non]. Esso diventa successivamente necessarie per gestire e commerciali, ma il metodo è pubblico, cambiando di espandersi &a &amp;potrebbe rompere codice esterno che effettua la propria &-a-- &amp;sostituzione. Se il metodo è privato, tuttavia, potrebbe essere risolto per la gestione &senza causare problemi per alcun codice esterno.
supercat

Questo è un problema interessante per non dire altro, ma non vedo come essere statico lo renda più un problema che non essere statico, che è la chiave di questo problema. Se seguiamo la tua logica, tutto ovunque reimplementerebbe tutto perché "omg, cosa succederebbe se un bug o i requisiti cambiassero un giorno?"
corsiKa

26

Un motivo abbastanza comune (in Java) sarebbe l'inizializzazione di variabili di campo immutabili in un costruttore utilizzando un private staticmetodo semplice per ridurre il disordine del costruttore.

  • È private: le classi esterne non dovrebbero vederlo.
  • È static: può eseguire alcune operazioni, 1 indipendente dallo stato della classe host.

Un esempio in qualche modo inventato segue ...

per esempio:

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 Supponendo che non abbia interazione con altre staticvariabili.


15
Ciò è ancora più prezioso quando è necessario passare argomenti derivati ​​(calcolati) a un costruttore di superclassi. La super(...)chiamata deve essere la prima riga del costruttore della tua classe, quindi non puoi dichiarare le variabili locali per aiutarti a capire cosa passare alla super chiamata. Tuttavia, puoi chiamare metodi statici (privati), che usano tutte le linee necessarie per calcolare il valore da passare al super costruttore.
Andrzej Doyle,

si noti che esiste la possibilità di un blocco di inizializzazione statico
Franz Ebner

13

Un caso d'uso comune per un private staticmetodo è un metodo di utilità che è

  1. usato solo da quella classe
  2. è indipendente dallo stato interno di quella classe

12

Vedi che hai alcune righe di codice che si ripetono in molti dei tuoi metodi, quindi decidi di estrarle in un singolo metodo, poiché il codice duplicato non va bene.

Rendi privato il metodo in quanto non è progettato per un uso diffuso e non desideri che il codice non correlato lo chiami. (Discuti questo punto nei commenti ....)

Poiché il metodo non accede ad alcun campo di istanza, può essere statico, rendendolo statico rendendolo più facile da capire e forse anche un po 'più veloce.

Quindi .... (Forse ora, forse più tardi, forse mai)

Una volta che il metodo è stato reso statico, è chiaro che può essere spostato fuori dalla classe, diciamo a una classe di unità.

È anche facile trasformarlo in un metodo di istanza di uno dei suoi parametri, spesso è qui che dovrebbe essere il codice.


Mi piace questa risposta, ma hai qualche riferimento aggiornato per questo? "e forse anche un po 'più veloce"
Magnilex,

@Magnilex, Il puntatore "this" non viene passato ai metodi di classe statici, quindi tenderanno ad essere più veloci dei metodi di istanza statici, a meno che il compilatore non rilevi che "this" non viene utilizzato nel metodo di istanza (improbabile).
Ian,

2

Posso pensare ad almeno due ragioni per cui avresti bisogno di un metodo privato statico su una classe.

1: le tue istanze hanno motivo di chiamare un metodo statico che non desideri venga chiamato direttamente, forse perché condivide i dati tra tutte le istanze della tua classe.

2: i tuoi metodi statici pubblici hanno subroutine che non desideri vengano chiamate direttamente. Il metodo viene ancora chiamato senza un'istanza, ma non direttamente.

Naturalmente, "aiuta la classe a dare un senso" è una buona ragione da sola.


1

Generalmente, se trovo che sto scrivendo metodi statici privati, lo prendo come un'indicazione che c'è qualcosa che avrei dovuto modellare separatamente.

Poiché non sono legati allo stato di una particolare istanza di oggetto, una raccolta di metodi statici pubblici e privati ​​potrebbe formare una classe completamente separata con la sua semantica e metodi non statici.

(Un altro suggerimento è che se trovo che ho molti metodi statici (pubblici e privati) che hanno tutti un parametro comune di qualche tipo, potrebbero essere meglio come membri di quel tipo.)

Pertanto, per rispondere alla tua domanda, vengono visualizzati metodi statici privati ​​quando una classe fornisce un gruppo di metodi correlati indipendenti da un'istanza di quella classe. (... e poiché sono indipendenti, potrebbero stare meglio nella loro classe.)


-1

Un esempio molto semplice che mi viene in mente è, se si desidera eseguire alcune elaborazioni su argomenti di input (o alcune manipolazioni) che vengono passate alla funzione principale. Quindi in questo caso se l'elaborazione è grande e la stessa funzionalità non verrà utilizzata da nessun'altra parte, avrà senso avere una funzione privata in quanto non verrà utilizzata / chiamata da nessun'altra parte + statica poiché main è statica.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.