Java - Modificatori non di accesso

Java fornisce una serie di modificatori non di accesso per ottenere molte altre funzionalità.

  • Il modificatore statico per la creazione di variabili e metodi di classe.

  • Il modificatore finale per finalizzare le implementazioni di classi, metodi e variabili.

  • Il modificatore astratto per creare classi e metodi astratti.

  • I modificatori sincronizzati e volatili , utilizzati per i thread.

Il modificatore statico

Variabili statiche

La parola chiave statica viene utilizzata per creare variabili che esisteranno indipendentemente da qualsiasi istanza creata per la classe. Esiste solo una copia della variabile statica indipendentemente dal numero di istanze della classe.

Le variabili statiche sono note anche come variabili di classe. Le variabili locali non possono essere dichiarate statiche.

Metodi statici

La parola chiave statica viene utilizzata per creare metodi che esisteranno indipendentemente da qualsiasi istanza creata per la classe.

I metodi statici non utilizzano variabili di istanza di alcun oggetto della classe in cui sono definiti. I metodi statici prendono tutti i dati dai parametri e calcolano qualcosa da quei parametri, senza alcun riferimento alle variabili.

È possibile accedere alle variabili e ai metodi di classe utilizzando il nome della classe seguito da un punto e il nome della variabile o del metodo.

Example

Il modificatore statico viene utilizzato per creare variabili e metodi di classe, come nell'esempio seguente:

public class InstanceCounter {

   private static int numInstances = 0;

   protected static int getCount() {
      return numInstances;
   }

   private static void addInstance() {
      numInstances++;
   }

   InstanceCounter() {
      InstanceCounter.addInstance();
   }

   public static void main(String[] arguments) {
      System.out.println("Starting with " + InstanceCounter.getCount() + " instances");

      for (int i = 0; i < 500; ++i) {
         new InstanceCounter();
      }
      System.out.println("Created " + InstanceCounter.getCount() + " instances");
   }
}

Questo produrrà il seguente risultato:

Output

Started with 0 instances
Created 500 instances

Il modificatore finale

Variabili finali

Una variabile finale può essere inizializzata esplicitamente solo una volta. Una variabile di riferimento dichiarata final non può mai essere riassegnata per fare riferimento a un oggetto diverso.

Tuttavia, i dati all'interno dell'oggetto possono essere modificati. Quindi, lo stato dell'oggetto può essere modificato ma non il riferimento.

Con le variabili, il modificatore finale viene spesso utilizzato con static per rendere la costante una variabile di classe.

Example

public class Test {
   final int value = 10;

   // The following are examples of declaring constants:
   public static final int BOXWIDTH = 6;
   static final String TITLE = "Manager";

   public void changeValue() {
      value = 12;   // will give an error
   }
}

Metodi finali

Un metodo finale non può essere sovrascritto da nessuna sottoclasse. Come accennato in precedenza, il modificatore finale impedisce che un metodo venga modificato in una sottoclasse.

L'intenzione principale di rendere definitivo un metodo sarebbe che il contenuto del metodo non dovrebbe essere modificato da nessun estraneo.

Example

Dichiari i metodi utilizzando il modificatore finale nella dichiarazione della classe, come nell'esempio seguente:

public class Test {
   public final void changeName() {
      // body of method
   }
}

Classi finali

Lo scopo principale dell'utilizzo di una classe dichiarata come finale è impedire che la classe venga sottoclasse. Se una classe è contrassegnata come finale, nessuna classe può ereditare alcuna caratteristica dalla classe finale.

Example

public final class Test {
   // body of class
}

Il modificatore astratto

Classe astratta

Una classe astratta non può mai essere istanziata. Se una classe viene dichiarata astratta, l'unico scopo è che la classe venga estesa.

Una classe non può essere sia astratta che finale (poiché una classe finale non può essere estesa). Se una classe contiene metodi astratti, la classe dovrebbe essere dichiarata astratta. In caso contrario, verrà generato un errore di compilazione.

Una classe astratta può contenere sia metodi astratti che metodi normali.

Example

abstract class Caravan {
   private double price;
   private String model;
   private String year;
   public abstract void goFast();   // an abstract method
   public abstract void changeColor();
}

Metodi astratti

Un metodo astratto è un metodo dichiarato senza alcuna implementazione. Il corpo del metodo (implementazione) è fornito dalla sottoclasse. I metodi astratti non possono mai essere definitivi o rigorosi.

Qualsiasi classe che estende una classe astratta deve implementare tutti i metodi astratti della super classe, a meno che anche la sottoclasse non sia una classe astratta.

Se una classe contiene uno o più metodi astratti, la classe deve essere dichiarata astratta. Una classe astratta non ha bisogno di contenere metodi astratti.

Il metodo astratto termina con un punto e virgola. Esempio: public abstract sample ();

Example

public abstract class SuperClass {
   abstract void m();   // abstract method
}

class SubClass extends SuperClass {
   // implements the abstract method
   void m() {
      .........
   }
}

Il modificatore sincronizzato

La parola chiave sincronizzata utilizzata per indicare che un metodo è accessibile da un solo thread alla volta. Il modificatore sincronizzato può essere applicato con uno qualsiasi dei quattro modificatori del livello di accesso.

Example

public synchronized void showDetails() {
   .......
}

Il modificatore transitorio

Una variabile di istanza è contrassegnata come transitoria per indicare alla JVM di ignorare la particolare variabile durante la serializzazione dell'oggetto che la contiene.

Questo modificatore è incluso nell'istruzione che crea la variabile, che precede la classe o il tipo di dati della variabile.

Example

public transient int limit = 55;   // will not persist
public int b;   // will persist

Il modificatore volatile

Il modificatore volatile viene utilizzato per far sapere alla JVM che un thread che accede alla variabile deve sempre unire la propria copia privata della variabile con la copia master in memoria.

L'accesso a una variabile volatile sincronizza tutte le variabili copiate nella cache nella memoria principale. Volatile può essere applicato solo alle variabili di istanza, che sono di tipo oggetto o private. Un riferimento a un oggetto volatile può essere nullo.

Example

public class MyRunnable implements Runnable {
   private volatile boolean active;

   public void run() {
      active = true;
      while (active) {   // line 1
         // some code here
      }
   }

   public void stop() {
      active = false;   // line 2
   }
}

Di solito, run () viene chiamato in un thread (quello che inizi a usare Runnable) e stop () viene chiamato da un altro thread. Se nella riga 1 viene utilizzato il valore memorizzato nella cache di active, il ciclo potrebbe non interrompersi quando si imposta active su false nella riga 2. È allora che si desidera utilizzare volatile .