MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Membrii statici și modificatorul static

În afară de metodele și câmpurile obișnuite, o clasă poate avea câmpuri statice, metode, constante și inițializatori. De exemplu, clasa principală a programului are metoda main, care este statică:

public static void main(String[] args) {
   
}

Pentru a declara variabile, constante, metode și inițializatori statici, se utilizează cuvântul cheie static înainte de declarație.

Câmpuri statice

La crearea obiectelor unei clase, pentru fiecare obiect se creează o copie a câmpurilor non-statice. În schimb, câmpurile statice sunt comune pentru întreaga clasă și pot fi utilizate fără a crea obiecte ale clasei.

De exemplu, să creăm o variabilă statică:

public class Program {
     
   public static void main(String[] args) {
       
       Person tom = new Person();
       Person bob = new Person();
       
       tom.displayId();    // Id = 1
       bob.displayId();    // Id = 2
       System.out.println(Person.counter); // 3
       
       // modificăm Person.counter
       Person.counter = 8;
       
       Person sam = new Person();
       sam.displayId();    // Id = 8
   }
}

class Person {
   
   private int id;
   static int counter = 1;
   
   Person() {
       id = counter++;
   }

   public void displayId() {
       System.out.printf("Id: %d \n", id);
   }
}

Clasa Person conține variabila statică counter, care crește în constructor și a cărei valoare este atribuită variabilei id. Astfel, la crearea fiecărui nou obiect Person, această variabilă va crește, ceea ce face ca fiecare nou obiect Person să aibă un câmp id mai mare cu 1 decât cel precedent.

Deoarece variabila counter este statică, putem accesa aceasta prin numele clasei:

System.out.println(Person.counter); // obținem valoarea
Person.counter = 8;                 // modificăm valoarea

Ieșirea în consolă a programului:

Id = 1
Id = 2
3
Id = 8

Constante statice

De asemenea, pot exista constante statice, care sunt comune pentru întreaga clasă.

public class Program {
     
   public static void main(String[] args) {
       
       double radius = 60;
       System.out.printf("Radius: %f \n", radius);             // 60
       System.out.printf("Area: %f \n", Math.PI * radius);     // 188,4
   }
}

class Math {
   public static final double PI = 3.14;
}

Este de remarcat că pe parcursul temelor anterioare au fost deja utilizate constant statice, cum ar fi out din expresia:

System.out.println("hello");

out reprezintă o constantă statică a clasei System, motiv pentru care este accesibilă fără a crea un obiect al clasei System.

Inițializatori statici

Inițializatorii statici sunt folosiți pentru a inițializa variabilele statice sau pentru a executa anumite acțiuni la crearea primului obiect al clasei. De exemplu:

public class Program {
     
   public static void main(String[] args) {
       
       Person tom = new Person();
       Person bob = new Person();
       
       tom.displayId();    // Id = 105
       bob.displayId();    // Id = 106
   }
}

class Person {
   
   private int id;
   static int counter;
   
   static {
       counter = 105;
       System.out.println("Static initializer");
   }
   
   Person() {
       id = counter++;
       System.out.println("Constructor");
   }
   
   public void displayId() {
       System.out.printf("Id: %d \n", id);
   }
}

Inițializatorul static este definit la fel ca unul obișnuit, doar că este precedat de cuvântul cheie static. În acest caz, inițializatorul static setează valoarea inițială a câmpului static counter și afișează un mesaj în consolă.

În program, se creează două obiecte ale clasei Person. Ieșirea în consolă va arăta astfel:

Static initializer
Constructor
Constructor
Id: 105
Id: 106

Este important de reținut că apelul inițializatorului static se face după încărcarea clasei și, practic, înainte de crearea primului obiect al clasei.

Metode statice

Metodele statice sunt asociate întregii clase. De exemplu, în codul anterior, variabila statică counter era accesibilă din afara clasei și am putut să îi modificăm valoarea. Să facem această variabilă inaccesibilă pentru modificare din afară, dar disponibilă pentru citire printr-o metodă statică:

public class Program {
     
   public static void main(String[] args) {
       
       Person.displayCounter();    // Counter: 1
       
       Person tom = new Person();
       Person bob = new Person();
       
       Person.displayCounter();    // Counter: 3
   }
}

class Person {
   
   private int id;
   private static int counter = 1;
   
   Person() {
       id = counter++;
   }

   // metodă statică
   public static void displayCounter() {
       System.out.printf("Counter: %d \n", counter);
   }

   public void displayId() {
       System.out.printf("Id: %d \n", id);
   }
}

Acum variabila statică nu mai este accesibilă din afara clasei, fiind privată. Valoarea ei este afișată prin metoda statică displayCounter. Pentru a apela metoda statică, folosim numele clasei: Person.displayCounter().

Atunci când folosim metode statice, trebuie să ținem cont de limitări: în metodele statice putem apela doar alte metode statice și putem folosi doar variabile statice.

Metodele sunt definite ca statice atunci când nu afectează starea obiectului, adică câmpurile și constantele non-statice, și nu este necesar să creăm o instanță a clasei pentru a le apela. De exemplu:

public class Program {
     
   public static void main(String[] args) {
           
       System.out.println(Operation.sum(45, 23));          // 68
       System.out.println(Operation.subtract(45, 23));     // 22
       System.out.println(Operation.multiply(4, 23));      // 92
   }
}

class Operation {
   
   static int sum(int x, int y) {
       return x + y;
   }

   static int subtract(int x, int y) {
       return x - y;
   }

   static int multiply(int x, int y) {
       return x * y;
   }
}

În acest caz, pentru metodele sum, subtract, multiply nu contează ce instanță a clasei Operation este folosită. Aceste metode lucrează doar cu parametrii lor și nu afectează starea clasei. De aceea, ele pot fi definite ca statice.

← Lecția anterioară Lecția următoare →