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 .