JavaRush /Java Blog /Random-IT /10 Note sul modificatore statico in Java

10 Note sul modificatore statico in Java

Pubblicato nel gruppo Random-IT
Il modificatore statico in Java è direttamente associato alla classe. Se il campo è statico allora appartiene alla classe, se il metodo è statico è la stessa cosa: appartiene alla classe. In base a ciò, puoi accedere a un metodo o campo statico utilizzando il nome della classe. Ad esempio, se il campo count è statico nella classe Counter, puoi accedere alla variabile con una query come: Counter.count. 10 Note sul modificatore statico in Java - 1Prima di iniziare con le note, ricordiamo (e magari scopriamo) cos'è statico e cosa può essere statico in Java. Static è un modificatore applicato a un campo, blocco, metodo o classe interna. Questo modificatore indica che il soggetto è legato alla classe corrente.

Campi statici

Quando denotiamo una variabile di livello classe, indichiamo che il valore appartiene a una classe. Se non lo fai, il valore della variabile verrà associato a un oggetto creato utilizzando questa classe. Cosa significa? 10 Note sul modificatore statico in Java - 2E il fatto è che se la variabile non è statica, allora ogni nuovo oggetto di questa classe avrà il proprio valore di questa variabile, cambiandola la modifichiamo esclusivamente in un oggetto: ad esempio, abbiamo una classe Car con un non -variabile statica:
public class Car {
  int km;
}
Quindi in principale:
Car orangeCar = new Car();
orangeCar.km = 100;

Car blueCar = new Car();
blueCar.km = 85;

System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
L'output che otteniamo è:

Orange car - 100
Blue car - 85
Come puoi vedere, ogni oggetto ha la propria variabile, la cui modifica avviene solo per questo oggetto. Bene, se abbiamo una variabile statica, allora questo valore globale è lo stesso per tutti: Ora abbiamo un'auto con una variabile statica:
public class Car {
  static int km;
}
Quindi lo stesso codice in main verrà restituito alla console:

Orange car - 85
Blue car - 85
Dopotutto, abbiamo una variabile per tutti noi e ogni volta la cambiamo. Di solito si accede alle variabili statiche non tramite un riferimento all'oggetto - orangeCar.km, ma tramite il nome della classe - Car.km

Blocco statico

Esistono due blocchi di inizializzazione: regolare e statico. Il blocco ha lo scopo di inizializzare le variabili interne. Se il blocco è normale, le variabili interne dell'oggetto vengono inizializzate con esso, ma se è statico, vengono assegnate variabili statiche (ovvero variabili di classe). Esempio di una classe con un blocco di inizializzazione statico:
public class Car {
  static int km;

  static {
     km = 150;
  }
}

Metodo statico

I metodi statici differiscono dai metodi normali in quanto sono anch'essi legati a una classe anziché a un oggetto. Una proprietà importante di un metodo statico è che può accedere solo a variabili/metodi statici. Ad esempio, diamo un'occhiata a una classe che sarà una sorta di contatore che tiene traccia delle chiamate ai metodi:
public class Counter {
  static int count;

  public static void invokeCounter() {
     count++;
     System.out.println("Current counter value - " + count);
  }
}
Chiamiamolo in main:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
E otteniamo l'output sulla console:

Текущее meaning счётчика - 1
Текущее meaning счётчика - 2
Текущее meaning счётчика - 3

Classe statica in Java

Solo una classe interna può essere una classe statica. Ancora una volta, questa classe è legata alla classe esterna e se quella esterna viene ereditata da un'altra classe, questa non verrà ereditata. Inoltre, questa classe può essere ereditata, così come può essere ereditata da qualsiasi altra classe e implementare un'interfaccia. Essenzialmente, una classe nidificata statica non è diversa da qualsiasi altra classe interna, tranne per il fatto che il suo oggetto non contiene un riferimento all'oggetto della classe esterna che l'ha creata. Tuttavia, questo rende una classe statica molto simile a una normale non annidata, perché l'unica differenza è che è racchiusa in un'altra classe. In alcuni casi questo è per noi un vantaggio poiché da esso abbiamo accesso alle variabili statiche private della classe esterna. Esempio di una classe statica nidificata:
public class Vehicle {

  public static class Car {
     public int km;
  }
}
Creando un'istanza di questa classe e impostando il valore della variabile interna:
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
Per utilizzare metodi/variabili/classi statiche, non è necessario creare un oggetto di quella classe. Naturalmente, i modificatori di accesso dovrebbero essere presi in considerazione. Ad esempio, i campi privatesono accessibili solo all'interno della classe in cui sono dichiarati. I campi protectedsono disponibili per tutte le classi all'interno di un pacchetto ( package ), nonché per tutte le classi discendenti all'esterno del pacchetto. Per maggiori dettagli, consulta l’articolo “ privato vs protetto vs pubblico ”. increment()Supponiamo che nella classe sia presente un metodo statico Counteril cui compito è incrementare il contatore count. Per chiamare questo metodo, è possibile utilizzare un'invocazione nel formato Counter.increment(). Non è necessario creare un'istanza di una classe Counterper accedere a un campo o metodo statico. Questa è la differenza fondamentale tra oggetti statici e NON statici (membri della classe). Permettimi di ricordarti ancora una volta che i membri della classe statica appartengono direttamente alla classe, non alla sua istanza. Cioè, il valore di una variabile statica countsarà lo stesso per tutti gli oggetti di tipo Counter. Più avanti in questo articolo esamineremo gli aspetti fondamentali dell'utilizzo del modificatore statico in Java, nonché alcune funzionalità che ti aiuteranno a comprendere i concetti chiave della programmazione.

Ciò che ogni programmatore dovrebbe sapere sul modificatore Static in Java

In questa sezione verranno illustrate le nozioni di base sull'utilizzo di metodi, campi e classi statici. Cominciamo con le variabili.
  1. NON è possibile accedere ai membri non statici di una classe all'interno di un contesto statico, come un metodo o un blocco. La compilazione del codice seguente genererà un errore:

    public class Counter{
    private int count;
    public static void main(String args[]){
       System.out.println(count); //compile time error
    }}

    Questo è uno degli errori più comuni commessi dai programmatori Java, soprattutto dai principianti. Poiché il metodo mainè statico, ma la variabile countnon lo è, in questo caso il metodo printlnall'interno del metodo maingenererà "Errore in fase di compilazione".

  2. В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких How «состояние гонки» (race condition).

  3. Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый an object для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы How нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утorт (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утorты в Java финализированы (final).

  4. Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) instead of переопределения. Это явление известно How сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен How в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

    class Vehicle{
         public static void  kmToMiles(int km){
              System.out.println("Inside parent class/static method");
         } }
    
    class Car extends Vehicle{
         public static void  kmToMiles(int km){
              System.out.println("Inside child class/static method ");
         } }
    
    public class Demo{
       public static void main(String args[]){
          Vehicle v = new Car();
           v.kmToMiles(10);
      }}

    Вывод в консоль:

    Внутри родительского класса/статического метода

    Код наглядно демонстрирует: несмотря на то, что an object имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

  5. Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны How «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry, который предоставляет структуру данных внутри HashMap. Стоит заметить, также How и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявor пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator), например компаратор по возрасту (AgeComparator) в классе сотрудники (Employee).

  6. Модификатор static также может быть объявлен в статичном блоке, более известным How «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

  7. Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных or не статических методов, которые связываются во время исполнения на реальном an objectе. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности or необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утorты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.

  8. Важным свойством статического блока является инициализация. Статические поля or переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в Howом они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton. Если вы не используется список Enum How Singleton, по тем or иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того How кто-нибудь об этом «попросит». Если an object ресурсоёмкий or редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу.

  9. Durante la serializzazione, proprio come transientle variabili, i campi statici non vengono serializzati. Infatti, se salvi dei dati in un campo statico, dopo la deserializzazione il nuovo oggetto conterrà il suo valore primario (predefinito), ad esempio, se il campo statico era una variabile di tipo int, il suo valore dopo la deserializzazione sarà zero, se il tipo floatè 0.0, se tipo Objectnull. Onestamente, questa è una delle domande più frequenti sulla serializzazione nelle interviste Java. Non memorizzare i dati più importanti su un oggetto in un campo statico!

  10. E infine, parliamo di static import. Questo modificatore ha molto in comune con l'operatore standard importma, a differenza di esso, consente di importare uno o tutti i membri statici di una classe. Quando importiamo metodi statici, è possibile accedervi come se fossero definiti nella stessa classe, allo stesso modo quando importiamo campi, possiamo accedervi senza specificare il nome della classe. Questa funzionalità è stata introdotta nella versione 1.5 di Java e, se utilizzata correttamente, migliora la leggibilità del codice. Questa costruzione si trova più spesso nei test JUnit , perché Quasi tutti gli sviluppatori di test utilizzano static importmetodi assert, ad esempio, assertEquals()e i loro duplicati sovraccarichi. Se nulla è chiaro, benvenuti per ulteriori informazioni .

È tutto. Ogni programmatore deve conoscere tutti i punti precedenti relativi al modificatore statico in Java . Questo articolo tratta le informazioni di base su variabili statiche, campi, metodi, blocchi di inizializzazione e importazioni. Incluse alcune proprietà importanti, la cui conoscenza è fondamentale quando si scrivono e si comprendono programmi in Java. Spero che ogni sviluppatore perfezioni le proprie capacità nell'utilizzo di concetti statici perché... Questo è molto importante per una programmazione seria."
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION