Când să utilizați metode statice (Programare, Java, Metode Statice)

KP65 a intrebat.

Mă întreb când să folosesc metode statice? Să zicem că am o clasă cu câțiva getters și setters, o metodă sau două, și vreau ca aceste metode să fie invocabile doar pe un obiect instanță al clasei. Asta înseamnă că ar trebui să folosesc o metodă statică?

Exemplu:

Obj x = new Obj();
x.someMethod();

…sau:

Obj.someMethod(); // Is this the static way?

Sunt destul de confuz!

22 răspunsuri
not-just-yeti

O regulă de bază: întreabă-te „Are sens să apelezi această metodă, chiar dacă nu a fost construit încă niciun obiect?”. Dacă da, ar trebui să fie cu siguranță statică.

Deci, într-o clasă Car ați putea avea o metodă:

double convertMpgToKpl(double mpg)

…care ar fi statică, deoarece cineva ar putea dori să știe la ce se convertește 35mpg, chiar dacă nimeni nu a construit vreodată un Car. Dar această metodă (care stabilește eficiența unui anumit Car):

void setMileage(double mpg)

…nu poate fi statică, deoarece este de neconceput să se apeleze metoda înainte de orice Car a fost construită.

(Apropo, inversul nu este întotdeauna adevărat: s-ar putea să aveți uneori o metodă care implică două metode Car obiecte, și totuși să doriți ca aceasta să fie statică. De exemplu:

Car theMoreEfficientOf(Car c1, Car c2)

Deși aceasta ar putea fi convertită într-o versiune nestatică, unii ar susține că, din moment ce nu există o alegere „privilegiată” pentru care Car este mai importantă, nu ar trebui să forțați apelantul să aleagă una dintre ele. Car ca obiect pe care va invoca metoda. Totuși, această situație reprezintă o fracțiune destul de mică din toate metodele statice.

Comentarii

    340

  • Câteva exemple bune aici. Aș adăuga, totuși, că „static” este adesea valoros atunci când știți că ceva nu se va schimba între instanțe. În acest caz, aș lua în considerare cu adevărat „principiul responsabilității unice”, care presupune că o clasă ar trebui să aibă o singură responsabilitate și, prin urmare, un singur motiv de schimbare. Cred că ar trebui să se ia în considerare mutarea funcției „ConvertMpgToKpl(double mpg)” și a metodelor similare în propria clasă. Scopul unui obiect mașină este de a permite instanțierea mașinilor, nu de a oferi o comparație între ele. Acestea ar trebui să fie externe clasei. –  > Por Zack Jannsen.
  • 35

  • Cred că aș prefera metoda Car#isMoreEfficientThan(Car). Are avantajul că mașina pe care o returnezi în caz de egalitate nu este arbitrară. Este evident din titlul metodei ce se returnează în caz de egalitate. –  > Por Cruncher.
  • De asemenea, aș fi atent la crearea unei metode statice care folosește o resursă externă (sistem de fișiere, bază de date etc.) acest tip de statică poate face îngrozitoare testarea metodelor consumatoare. Eu personal încerc să păstrez statica în domeniul „utilității”. –  > Por Seth M..
  • De fapt, ar trebui să fie implementată ca un Comparator. –  > Por Dogweather.
  • @B1KMusic Bineînțeles. Ceea ce vreau să spun prin „care mașină este returnată în caz de egalitate” este „true se referă la mașina apelată, iar false se referă la mașina trecută”. Este fără ambiguitate. –  > Por Cruncher.
Mohd

Definiți metodele statice numai în următoarele scenarii:

  1. Dacă scrieți clase de utilitate și acestea nu trebuie să fie modificate.
  2. Dacă metoda nu utilizează nicio variabilă de instanță.
  3. Dacă nicio operațiune nu depinde de crearea instanței.
  4. În cazul în care există un cod care poate fi ușor partajat de toate metodele de instanță, extrageți codul respectiv într-o metodă statică.
  5. Dacă sunteți sigur că definiția metodei nu va fi niciodată modificată sau suprascrisă. Deoarece metodele statice nu pot fi suprascrise.

Comentarii

    48

  • puncte bune, dar acestea reprezintă cerințe dacă doriți să faceți o metodă statică, nu motive pentru a o face statică. –  > Por tetsuo.
  • @Mohd despre cerința 5: Când poți fi 100% sigur că o metodă nu va fi niciodată modificată sau suprascrisă? Nu există întotdeauna factori necunoscuți pe care nu îi poți lua în considerare în momentul în care scrii metoda statică? –  > Por PixelPlex.
  • „Utility-Classes” sunt foarte dificil de raționalizat, partea proastă este că mai devreme sau mai târziu totul începe să „arate ca un utilitar (da, mă refer la acel pachet „util” care este umflat, de neatins și prost testat), iar cazurile de testare vor avea nevoie de mai multă muncă (să te joci cu utilitarii statici este DIFICIL). Preferați mai întâi obiectele. –  > Por Sergio.
  • @Mohd acest răspuns este exact ceea ce căutam. M-am confruntat cu o mulțime de probleme în utilizarea metodelor statice în multithreading. Poți te rog să elaborezi mai mult punctele 2, 3 (cu exemplu 100 thumbs up pentru tine) – -.  > Por Prakash Pandey.
  • Cred că ar trebui inventată o „clasă statică” dacă aveți de gând să folosiți variabile și metode statice. –  > Por Robert Rocha.
tetsuo

Există câteva motive valabile pentru a utiliza metode statice:

  • Performanță: dacă vrei ca un anumit cod să fie executat și nu vrei să instanțiezi un obiect suplimentar pentru a face acest lucru, bagă-l într-o metodă statică. De asemenea, JVM-ul poate optimiza mult metodele statice (cred că am citit odată că James Gosling a declarat că nu ai nevoie de instrucțiuni personalizate în JVM, deoarece metodele statice vor fi la fel de rapide, dar nu am putut găsi sursa – deci ar putea fi complet fals). Da, este o micro-optimizare și, probabil, inutilă. Iar noi, programatorii, nu facem niciodată lucruri inutile doar pentru că sunt cool, nu-i așa?

  • Practicitate: în loc de a apela new Util().method(arg), sunați Util.method(arg), sau method(arg) cu importuri statice. Mai ușor, mai scurt.

  • Adăugarea de metode: ați dorit cu adevărat ca clasa String să aibă o metodă removeSpecialChars() metodă de instanță, dar nu există (și nu ar trebui să existe, deoarece caracterele speciale ale proiectului dvs. pot fi diferite de cele ale celuilalt proiect) și nu o puteți adăuga (deoarece Java este oarecum sănătos), așa că creați o clasă utilitară și apelați removeSpecialChars(s) în loc de s.removeSpecialChars(). Dulce.

  • Puritate: luându-vă câteva precauții, metoda dvs. statică va fi o metodă funcție pură, adică singurul lucru de care depinde sunt parametrii săi. Date în intrare, date în ieșire. Acest lucru este mai ușor de citit și de depanat, deoarece nu trebuie să vă faceți griji cu privire la ciudățeniile moștenirii. Puteți face acest lucru și cu metodele de instanță, dar compilatorul vă va ajuta un pic mai mult cu metodele statice (nepermițând referințe la atributele de instanță, suprascrierea metodelor etc.).

De asemenea, va trebui să creați o metodă statică dacă doriți să faceți un singleton, dar… nu o faceți. Adică, gândiți-vă de două ori.

Acum, mai important, de ce nu ați vrea să creați o metodă statică? În principiu, polimorfismul dispare pe fereastră. Nu veți putea suprascrie metoda, și nici să o declarați într-o interfață (pre-Java 8). Acest lucru elimină o mare parte din flexibilitatea proiectului dumneavoastră. De asemenea, dacă aveți nevoie de stare, veți ajunge să aveți o mulțime de erori de concurență și/sau blocaje dacă nu sunteți atent.

Comentarii

  • Aici sunt enumerate o mulțime de motive bune pentru care statica poate fi utilă. Încă unul la care mă pot gândi este că scrierea de teste unitare pentru astfel de metode este pur și simplu simplă –  > Por nilesh.
  • @tetsuo Mulțumesc! Explicația ta este foarte clară, iar motivele furnizate sunt foarte logice și au mult sens. –  > Por Deniss M..
  • Iar noi, programatorii, nu facem niciodată lucruri inutile doar pentru că sunt cool, nu-i așa? +1 –  > Por Scaramouche.
  • Acestea fiind spuse, o metodă statică devine o funcție cu nume complet stackoverflow.com/questions/155609/… –  > Por Ivanzinho.
  • Sunt de acord cu Performanța și Practicitatea, dar nu și cu Puritatea. Metoda statică poate modifica membrii statici ai clasei (care pot fi privați). Acest lucru poate fi util. De exemplu, ați putea avea o metodă de genul „static synchronized int allocateID() {return idNext++;}”. De fapt, o metodă statică poate fi la fel de pură sau impură ca o metodă nestatică în ceea ce privește efectele secundare. –  > Por Adam Gawne-Cain.
Alfred

După ce am citit articolele lui Misko, cred că metodele statice sunt rele din punct de vedere al testării. Ar trebui să aveți fabrici în schimb (poate folosind un instrument de injecție a dependențelor precum Guice).

cum mă asigur că am doar una din ceva

să am doar unul din ceva Problema „cum mă asigur că am doar unul din ceva” este ocolită în mod plăcut. Instanțiați o singură ApplicationFactory în fișierul principal și, ca urmare, instanțiați o singură instanță a tuturor singletonilor dumneavoastră.

Problema de bază a metodelor statice este că acestea sunt cod procedural.

Problema de bază a metodelor statice este că acestea sunt cod procedural. Nu am nicio idee despre cum să testez unitar codul procedural. Testarea unitară presupune că pot instanția o parte a aplicației mele în mod izolat. În timpul instanțierii, conectez dependențele cu mocks/friendlies care înlocuiesc dependențele reale. În cazul programării procedurale nu este nimic de „cablat”, deoarece nu există obiecte, codul și datele sunt separate.

Comentarii

    21

  • Nu înțeleg partea în care se spune că nu se poate testa unitar codul procedural. Nu trebuie doar să stabilești cazuri de testare care să mapeze intrarea corectă la ieșirea corectă folosind metoda statică împreună cu clasa ca „unitate”? –  > Por tjb.
  • Ați putea face asta pentru a testa aceste funcții. Dar atunci când folosiți aceste metode statice în alte clase pe care doriți să le testați, cred că nu le puteți falsifica (mocks/friendlies) sau altceva, deoarece nu puteți instanția o clasă. –  > Por Alfred.
  • @Alfred: Vă rugăm să aruncați o privire la PowerMock care are capacitatea de a imita metode statice. Folosind PowerMock există puține scenarii, dacă există, în care să găsiți dependențe de metode care nu pot fi simulate. –  > Por Carles Sala.
  • Puteți testa unitar staticele folosind PowerMock, însă veți descoperi în curând că nu mai aveți spațiu Permgen (am făcut asta, am primit tricoul), și încă este urât. Dacă nu ȘTIȚI (pe baza a cel puțin un deceniu de experiență proprie în limbaje OO adevărate, nu migrând din C), atunci NU FACEȚI acest lucru. Serios, cel mai prost cod pe care l-am văzut vreodată a provenit din utilizarea staticii de către un dezvoltator embedded și, în cele mai multe cazuri, am rămas blocați cu ea, pentru totdeauna, iar adăugarea de mai mult cod nu făcea decât să ne blocheze și mai strâns în monolitul nemodificabil. Cuplare liberă: nu, testabil: abia dacă, modificabil: NICIODATĂ. Evitați! –  > Por user1016765.
  • Pot înțelege dificultatea de a testa metodele statice care depind de starea statică. Dar atunci când testați stateless metode statice precum Math.abs() sau Arrays.sort(), chiar și metodele pe care le puteți treceți toate dependențele în, nu văd cum ar putea împiedica vreodată testarea unitară. Aș spune că o regulă de bază simplă este următoarea: dacă aveți vreun motiv să vă bateți joc de logica procedurală, atunci nu o puneți într-o metodă statică. Eu nu am avut niciodată un motiv să mă joc de Arrays.sort() sau Math.abs(). –  > Por Andy.
Zishan

A static este un tip de metodă care nu are nevoie de inițializarea unui obiect pentru a fi apelată. Ați observat că static este utilizată în main în Java? Executarea programului începe de acolo fără a fi creat un obiect.

Luați în considerare următorul exemplu:

 class Languages 
 {
     public static void main(String[] args) 
     {
         display();
     }

     static void display() 
     {
         System.out.println("Java is my favorite programming language.");
     }
  }

Comentarii

  • cel mai bun răspuns de fapt –  > Por Yahya.
Kevin Sylvestre

Metodele statice în java aparțin clasei (nu unei instanțe a acesteia). Ele nu folosesc variabile de instanță și, de obicei, vor primi date de intrare de la parametri, vor efectua acțiuni asupra lor, apoi vor returna un rezultat. Metodele de instanță sunt asociate cu obiecte și, după cum sugerează și numele, pot folosi variabile de instanță.

duffymo

Nu, metodele statice nu sunt asociate cu o instanță; ele aparțin clasei. Metodele statice sunt al doilea exemplu al tău; metodele de instanță sunt primul.

Comentarii

  • Ar trebui să folosiți metode statice dacă nu aveți nevoie de manipulări ale stării obiectului. –  > Por MastAvalons.
IndianProgrammer1234

Dacă aplicați cuvântul cheie static cu orice metodă, aceasta este cunoscută ca metodă statică.

  1. O metodă statică aparține mai degrabă clasei decât obiectului unei clase.
  2. O metodă statică este invocată fără a fi necesară crearea unei instanțe a unei clase.
  3. O metodă statică poate accesa un membru static al datelor și poate modifica valoarea acestuia.
  4. O metodă statică poate fi accesată doar folosind numele unei clase cu punct nume static . . . . exemplu: Student9.change();
  5. Dacă doriți să utilizați câmpuri nestatice ale unei clase, trebuie să folosiți o metodă nestatică.

//Program de modificare a proprietății comune tuturor obiectelor(câmp static).

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 Indian BBDIT 222 American BBDIT 333 China BBDIT

Carsten

Metodele statice nu sunt asociate cu o instanță, deci nu pot accesa niciun câmp nestatic din clasă.

Ați folosi o metodă statică dacă metoda nu utilizează niciun câmp (sau numai câmpuri statice) al unei clase.

Dacă sunt utilizate câmpuri nestatice ale unei clase, trebuie să folosiți o metodă nestatică.

Comentarii

  • Răspuns clar, scurt și simplu. –  > Por Josi.
Charlie Seligman

Metodele statice trebuie apelate asupra clasei, iar metodele de instanță trebuie apelate asupra instanțelor clasei. Dar ce înseamnă asta în realitate? Iată un exemplu util:

O clasă de mașini poate avea o metodă de instanță numită Accelerate(). Puteți accelera o mașină numai dacă aceasta există (a fost construită) și, prin urmare, aceasta ar fi o metodă de instanță.

O clasă de mașini poate avea, de asemenea, o metodă de numărare numită GetCarCount(). Aceasta ar returna numărul total de mașini create (sau construite). În cazul în care nu a fost construită nicio mașină, această metodă ar returna 0, dar ar trebui să poată fi totuși apelată și, prin urmare, ar trebui să fie o metodă statică.

Sagar

De fapt, folosim proprietăți și metode statice într-o clasă, atunci când dorim să folosim o anumită parte a programului nostru ar trebui să existe acolo până când programul nostru se execută. Și știm că, pentru a manipula proprietățile statice, avem nevoie de metode statice, deoarece acestea nu fac parte din variabila de instanță. Iar fără metode statice, manipularea proprietăților statice necesită mult timp.

Comentarii

  • Păstrarea stării în variabilele statice este un lucru rău din mai multe motive – cum ar fi siguranța multi-threading, depanarea, încapsularea datelor etc. etc. Metodele statice sunt în regulă dacă sunt funcții pure (lucrează doar cu parametrii, fără a-i modifica). Un bun exemplu ar fi o clasă utilitară, de exemplu pentru calcule matematice. –  > Por Vladimir Demirev.
jamz

Folosiți o metodă statică atunci când doriți să puteți accesa metoda fără o instanță a clasei.

Comentarii

    32

  • Acest lucru nu oferă nicio justificare pentru proiectarea unui program. –  > Por adamjmarkham.
Finbarr

Static:Obj.someMethod

Utilizați static atunci când doriți să oferiți acces la nivelul clasei la o metodă, adică atunci când metoda trebuie să poată fi apelată fără o instanță a clasei.

Vaishak Suresh

Metodele statice nu trebuie să fie invocate asupra obiectului și atunci le folosiți. Exemplu: Main() este o metodă statică și nu creați un obiect pentru a o apela.

Comentarii

  • Ura! Uite unde am ajuns în timp ce căutam pe Google întrebări de începător Java! Este o lume mică 🙂 –  > Por Deepak.
  • @Deepak lume mică într-adevăr 🙂 –  > Por Vaishak Suresh.
Manju Yadav

Metodele și variabilele statice sunt o versiune controlată a funcțiilor și variabilelor „globale” din Java. În care metodele pot fi accesate ca classname.methodName() sau classInstanceName.methodName()adică metodele și variabilele statice pot fi accesate folosind numele clasei, precum și instanțele clasei.

Clasele nu pot fi declarate ca fiind statice (pentru că nu are sens. Dacă o clasă este declarată publică, poate fi accesată de oriunde), clasele interne pot fi declarate statice.

Amit Kaneria

Metodele statice pot fi utilizate în cazul în care

  • nu se dorește efectuarea unei acțiuni asupra unei instanțe (metode de utilitate)

    După cum s-a menționat în câteva dintre răspunsurile de mai sus în acest post, convertirea milelor în kilometri sau calcularea temperaturii din Fahrenheit în Celsius și invers. Cu aceste exemple care folosesc metoda statică, nu este nevoie să instanți un obiect complet nou în memoria heap. Luați în considerare următoarele

    1. new ABCClass(double farenheit).convertFarenheitToCelcium() 
    2. ABCClass.convertFarenheitToCelcium(double farenheit)
    

    prima creează o nouă amprentă de clasă pentru fiecare invocare a unei metode, Performanță, Practică. Exemplele de mai jos sunt clasa Math și clasa StringUtils din biblioteca Apache-Commons:

    Math.random()
    Math.sqrt(double)
    Math.min(int, int)
    StringUtils.isEmpty(String)
    StringUtils.isBlank(String)
    
  • Se dorește să se utilizeze ca o funcție simplă. Intrările sunt trecute în mod explicit și se obțin datele rezultate ca valoare de returnare. Moștenirea, instanțierea obiectului nu intră în discuție. Concis, ușor de citit.

NOTĂ: Puțini sunt cei care se opun testabilității metodelor statice, dar și metodele statice pot fi testate! Cu jMockit, se pot imita metodele statice. Testabilitate. Exemplul de mai jos:

new MockUp<ClassName>() {
    @Mock
    public int doSomething(Input input1, Input input2){
        return returnValue;
    }
};

Metodele statice sunt metodele din Java care pot fi apelate fără a crea un obiect de clasă. Ele aparțin clasei.

Utilizăm metode statice atunci când nu este nevoie să invocăm o metodă folosind o instanță.

hemanto

O metodă statică are două scopuri principale:

  1. Pentru metodele de utilitate sau de ajutor care nu necesită starea obiectului.Deoarece nu este nevoie să acceseze variabilele de instanță, existența metodelor statice elimină necesitatea ca apelantul să instanțieze obiectul doar pentru a apela metoda.
  2. Pentru starea care este împărtășită de toate instanțele clasei, cum ar fi un contor. Toate instanțele trebuie să împartă aceeași stare. Metodele care utilizează pur și simplu această stare trebuie să fie, de asemenea, statice.

ave4496

În eclipse puteți activa un avertisment care vă ajută să detectați eventualele metode statice. (Deasupra liniei evidențiate se află o altă linie pe care am uitat să o evidențiez)

Ravindra babu

Mă întreb când să folosesc metode statice?

  1. O utilizare obișnuită pentru static este de a accesa static câmpuri.
  2. Dar puteți avea static metode, fără a face referire la static variabile. Metode auxiliare fără referințe static pot fi găsite în unele clase Java, cum ar fi java.lang.Math

    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
    
  3. Celălalt caz de utilizare, mă pot gândi la aceste metode combinate cu synchronized este punerea în aplicare a blocării la nivel de clasă într-un mediu cu mai multe fire de execuție.

Să zicem că am o clasă cu câțiva getters și setters, o metodă sau două, și vreau ca aceste metode să poată fi invocate numai de un obiect instanță al clasei. Aceasta înseamnă că ar trebui să folosesc o metodă statică?

Dacă aveți nevoie să accesați o metodă pe un obiect instanță al clasei, metoda dvs. ar trebui să nu fie statică.

Documentația Oracle pagina oferă mai multe detalii.

Nu sunt permise toate combinațiile de variabile și metode de instanță și de clasă:

  1. Metodele de instanță pot accesa direct variabilele de instanță și metodele de instanță.
  2. Metodele de instanță pot accesa direct variabilele de clasă și metodele de clasă.
  3. Metodele de clasă pot accesa direct variabilele de clasă și metodele de clasă.
  4. Metodele de clasă nu pot accesa direct variabilele de instanță sau metodele de instanță – ele trebuie să utilizeze o referință de obiect. De asemenea, metodele de clasă nu pot utiliza cuvântul cheie this, deoarece nu există o instanță la care să se facă referire.

Comentarii

  • Nu putem accesa câmpurile statice prin intermediul metodelor obișnuite? Atunci acest lucru A common use for static methods is to access static fields. nu este un argument. –  > Por parsecer.
Jake N

Am găsit o descriere frumoasă, când să folosiți metode statice:

Nu există reguli clare și rapide, bine scrise, pentru a decide când să faci o metodă statică sau nu, dar există câteva observații bazate pe experiență, care nu numai că ajută la a face o metodă statică, dar învață și când să folosești o metodă statică în Java. Ar trebui să luați în considerare posibilitatea de a face o metodă statică în Java:

  1. Dacă o metodă nu modifică starea obiectului sau dacă nu utilizează variabile de instanță.

  2. Doriți să apelați metoda fără a crea o instanță a clasei respective.

  3. O metodă este un bun candidat pentru a fi statică, dacă funcționează numai pe baza argumentelor care îi sunt furnizate, de exemplu public int factorial(int number){}, această metodă funcționează numai pe baza numărului furnizat ca argument.

  4. Metodele utilitare sunt, de asemenea, bune candidate pentru a fi statice, de exemplu StringUtils.isEmpty(String text), o metodă utilitară care verifică dacă un șir de caractere este gol sau nu.

  5. În cazul în care funcția metodei va rămâne statică în întreaga ierarhie a claselor, de exemplu, metoda equals() nu este un bun candidat pentru a deveni statică, deoarece fiecare clasă poate redefini egalitatea.

Sursa este aici

Amrit

Ori de câte ori nu doriți să creați un obiect pentru a apela o metodă în codul dumneavoastră, declarați metoda respectivă ca fiind statică. Deoarece metoda statică nu are nevoie de o instanță pentru a fi apelată, dar problema este că nu toate metodele statice sunt apelate automat de JVM. De acest privilegiu se bucură doar metoda main() „public static void main[String… args]” din java, deoarece în timpul execuției aceasta este metoda Signature public „static” void main[] căutată de JVM ca punct de intrare pentru a începe execuția codului.

Exemplu:

public class Demo
{
   public static void main(String... args) 
   {
      Demo d = new Demo();

      System.out.println("This static method is executed by JVM");

     //Now to call the static method Displ() you can use the below methods:
           Displ(); //By method name itself    
      Demo.Displ(); //By using class name//Recommended
         d.Displ(); //By using instance //Not recommended
   }

   public static void Displ()
   {
      System.out.println("This static method needs to be called explicitly");
   }
} 

Ieșire: – Această metodă statică este executată de JVMAceastă metodă statică trebuie să fie apelată în mod explicitAceastă metodă statică trebuie să fie apelată în mod explicitAceastă metodă statică trebuie să fie apelată în mod explicit