statica - java static variable



Tutti i metodi dovrebbero essere statici se la loro classe non ha variabili membro (14)

È una chiamata difficile. Ricorda cosa dice Josh Bloch sulle API :

Le API, come i diamanti, sono per sempre. Hai una possibilità di farlo bene, quindi dai il massimo.

(Questa potrebbe non essere un'API pubblica, ma se hai colleghi che useranno questo codice, in realtà è un'API). Se dichiari quei metodi statici, limiti la loro evoluzione futura e lo stato di incorporazione nella classe sarà difficile o impossibile. Dovrai convivere con le firme dei metodi statici. Se decidi di renderli non statici in fondo alla strada perché hai bisogno di stato, stai per rompere il codice cliente. Direi che, nel dubbio, non renderli statici. Detto questo, c'è un posto per le classi di utilità statiche che contengono un sacco di funzioni (ad esempio, calcola l'area di un cerchio). La tua classe potrebbe rientrare in quella categoria.

Ho appena avuto una discussione con qualcuno con cui lavoro e mi disturba molto. Se hai una classe che ha solo metodi come calculateRisk o / e calculatePrice , la classe è immutabile e non ha variabili membro, se i metodi sono statici in modo da non dover creare ogni volta un'istanza della classe. Io uso il seguente esempio:

public class CalcService {
  public int calcPrice(Trade trade, Date date) {
    ...
  }
  public double calcRisk(Trade trace, Date date) {
    ...
  }
}

Questi metodi dovrebbero essere static ?


Answer #1

Credo che i metodi stateless dovrebbero essere generalmente statici.

  • Nel codice è chiaro che nessun oggetto è coinvolto
  • Evita un'involuzione del costruttore priva di significato

Riesco a vedere infrangere questa regola per un'implementazione del modello strategico, come un certo numero di persone ha notato qui.


Answer #2

Dipende dal tuo obiettivo:

Se il tuo obiettivo è scrivere meno righe di codice possibili, l'approccio statico sarebbe il migliore.

Se il tuo obiettivo è la testabilità, abbiamo scoperto che i metodi statici sono un bugger da prendere in giro. Purtroppo, finiamo per scrivere un'interfaccia e una classe per alcuni di questi solo per essere in grado di deriderli facilmente.


Answer #3

Direi di sì, ma in questo caso si potrebbe anche fare un ragionamento semplicemente mettendo questi metodi sull'oggetto Trade.


Answer #4

In questi giorni c'è un sentimento generale contro le classi statiche, per ragioni di testabilità.

Questo perché le classi statiche non possono implementare un'interfaccia e quindi non possono essere facilmente sostituite per le classi di test, se necessario. Penso che casi come questo che trattano il prezzo siano un eccellente esempio di ciò. In futuro è possibile che ci siano molti modi per calcolare un prezzo, ed è bello poter sostituire questi calcolatori l'uno con l'altro a seconda delle necessità.

Potrebbe non essere utile ora, ma vedo più vantaggi nel non utilizzare una classe statica rispetto all'utilizzo di una.


Answer #5

In questo caso, probabilmente farei un paio di metodi statici. Suppongo che la funzione calc non dipenda da altre risorse per calcolare i valori, ed è generalmente segregata dal resto del codice.

In generale, tuttavia, tendo a evitare di fare cose troppo complicate con metodi statici. Se tu fossi un test unitario e volessi scambiare un MockCalcService, avere le chiamate statiche sparse nel tuo codice lo renderebbe molto difficile.


Answer #6

La classe che descrivi è semplicemente un insieme di funzioni che funzionano solo sugli input. È perfettamente ragionevole rendere tali funzioni metodi statici di una classe. In questo modo li raggruppa in modo logico ed elimina possibili conflitti di nome. La classe agisce infatti come uno spazio dei nomi e nient'altro.


Answer #7

La risposta è sì e no. Tutto dipende dallo scopo del comportamento del metodo. Per esempio:

  1. se questi metodi sono semplicemente metodi di utilità, allora ha perfettamente senso renderli statici.

  2. Se i metodi rappresentano una sorta di logica aziendale della tua applicazione (diciamo ... un'applicazione web), potresti voler renderli il più flessibili possibile. In questo caso, diventerebbero una semplice classe POJO, come metodi di istanza. Questo ha il vantaggio non tanto ovvio che possono essere convertiti in bean transazionali Spring, o anche bean di sessione EJB3 con uno sforzo minimo. Rende anche i metodi più facili da testare. È inoltre possibile creare interfacce per questo bean e aggiungere ulteriori aspetti ad esso nel modo desiderato.


Answer #8

Nelle risposte sopra ho letto l'argomento di non renderlo statico per ragioni di test. Non vedo perché, ma non sono familiair con la procedura di test che stai utilizzando.

Nella nostra azienda utilizziamo i test di unità e di sistema con Junit. (org.junit) Non c'è alcun problema a testare i metodi statici con questo pacchetto di test.

Quindi direi: sì, renderli statici.

(Con l'osservazione che non conosco la procedura di test in cui testare metodi statici è un problema)


Answer #9

Se lo fai statico, non puoi iniettare facilmente un'implementazione diversa.

Non ci sono più costi di runtime per chiamare metodi non statici, quindi per il nuovo codice evitare statico per quanto ragionevole.

OTOH, gli strumenti di refactoring possono sostituire tutte le chiamate a un metodo statico abbastanza facilmente, quindi non è fondamentale in un modo o nell'altro.

Non so se il calcolo dei prezzi o dei rischi possa variare nel tuo dominio. Se ci sono diverse strategie, il passaggio di un'implementazione di una strategia senza stato può avere benefici. Ma è più codice, e c'è una buona possibilità che YAGNI.


Answer #10

Secondo me dovrebbero essere statici. Potresti anche ottenere miglioramenti delle prestazioni perché il compilatore / jit potrebbe integrare i metodi


Answer #11

Vorrei rendere tutto statico.


Answer #12

Eviterei di fare queste statiche. Anche se al momento potrebbe avere un senso, in futuro potresti voler aggiungere qualche comportamento. ad esempio, al momento avresti un motore di calcolo predefinito (strategia):

CalcService cs = new CalcService();
cs.calcPrice(trade, date);

e in seguito potresti voler aggiungere un nuovo motore di calcolo:

CalcService cs = new CalcService(new WackyCalculationStrategy());
cs.calcPrice(trade, date);

Se rendi questa classe istantaneabile, puoi creare diverse istanze e passarle in giro, creare istantaneamente al volo, ecc. Puoi dare loro un comportamento di lunga durata (es. Quanti calcoli che coinvolgono il commercio X ha fatto questo oggetto? Ecc.)


Answer #13

Odore di statica

Nella maggior parte dei casi, un metodo statico è un esempio di comportamento separato dai dati. Indica che qualcosa non è incapsulato. Ad esempio, se vedi metodi validi per numero di telefono, e-mail ecc. in classi util, chiedi perché non sono questi campi non hanno le loro classi. Anche le classi di libreria possono essere estese per adattarsi al comportamento personalizzato. Infine, in casi speciali come java.lang.String (che è finale) potresti usare un myproject.String personalizzato (con comportamento aggiuntivo) che delega a java.lang.String

Gli oggetti sono il modo di accedere al comportamento nelle lingue OO. Non è utile preoccuparsi del costo dell'istanza dell'oggetto e dell'uso della statica. Per la maggior parte dei software aziendali, questo è un approccio "penny wise pound foolish" alle prestazioni.

A volte, si usano i functor (metodi che non usano lo stato dell'oggetto) per esprimere l'intento. Non significa che dovrebbero essere resi statici. Gli avvertimenti IDE che suggeriscono che "il metodo può essere reso statico" non dovrebbero essere presi sul serio.





static