Classi statiche in Java


947

C'è qualcosa di simile static classa Java?

Qual è il significato di tale classe. Devono essere staticanche tutti i metodi della classe statica ?

È richiesto il contrario, che se una classe contiene tutti i metodi statici, anche la classe deve essere statica?

A cosa servono le classi statiche?



Le classi statiche sono sostanzialmente utilizzate per raggruppare le classi insieme.
RockingDev

Risposte:


847

Java ha classi nidificate statiche ma sembra che tu stia cercando una classe statica di livello superiore. Java non ha modo di rendere statica una classe di livello superiore ma è possibile simulare una classe statica come questa:

  • Dichiara la tua classe final: impedisce l'estensione della classe poiché l'estensione di una classe statica non ha senso
  • Crea il costruttore private- Impedisce l'istanza per codice client in quanto non ha senso istanziare una classe statica
  • Crea tutti i membri e le funzioni della classe static: poiché non è possibile creare un'istanza della classe, non è possibile richiamare metodi di istanza o accedere ai campi di istanza
  • Nota che il compilatore non ti impedirà di dichiarare un membro di istanza (non statico). Il problema verrà visualizzato solo se si tenta di chiamare il membro dell'istanza

Esempio semplice per suggerimenti dall'alto:

public class TestMyStaticClass {
     public static void main(String []args){
        MyStaticClass.setMyStaticMember(5);
        System.out.println("Static value: " + MyStaticClass.getMyStaticMember());
        System.out.println("Value squared: " + MyStaticClass.squareMyStaticMember());
        // MyStaticClass x = new MyStaticClass(); // results in compile time error
     }
}

// A top-level Java class mimicking static class behavior
public final class MyStaticClass {
    private MyStaticClass () { // private constructor
        myStaticMember = 1;
    }
    private static int myStaticMember;
    public static void setMyStaticMember(int val) {
        myStaticMember = val;
    }
    public static int getMyStaticMember() {
        return myStaticMember;
    }
    public static int squareMyStaticMember() {
        return myStaticMember * myStaticMember;
    }
}

A che servono le classi statiche? Un buon uso di una classe statica è nel definire classi una tantum, di utilità e / o di libreria in cui l'istanza non avrebbe senso. Un grande esempio è la classe matematica che contiene alcune costanti matematiche come PI ed E e fornisce semplicemente calcoli matematici. Richiedere un'istanza in tal caso sarebbe inutile e confuso. Vedi la Mathclasse e il codice sorgente . Si noti che lo è finale tutti i suoi membri lo sono static. Se Java consentisse di dichiarare le classi di livello superiore, staticla classe Math sarebbe effettivamente statica.


35
una classe Foocon solo staticmetodi non è la stessa distatic class Foo
craigb

12
@Evorlor: se una classe viene dichiarata finale, i suoi metodi sono automaticamente (effettivamente) finali. Questo perché una classe finale non può essere sottoclassata e quindi i suoi metodi non possono essere sovrascritti (cioè, sono effettivamente finali). docs.oracle.com/javase/tutorial/java/IandI/final.html
jwayne

30
Questa risposta forse indirizza il significato dell'OP, ma (attualmente) non spiega le classi statiche Java, e quindi non risponde affatto alla domanda! Questo è molto male per le persone che arrivano qui cercando di capire cosa significa una classe statica in Java.
Tom,

12
@JBoy: Esiste una cosa come "classe statica" in Java, che è la domanda, ma questa risposta non spiega affatto. Invece, spiega come simulare in Java ciò che la risposta chiama una "classe statica" - ma che non è ciò che una "classe statica" in Java è! (Forse è quella che viene chiamata una "classe statica" in alcune altre lingue, ma le persone che vengono qui per conoscere le classi statiche di Java saranno fuorviate e confuse.)
Tom

4
dovresti menzionare esplicitamente che MyStaticClass () {// costruttore privato myStaticMember = 1; } NON avrà alcun effetto poiché il costruttore non verrà chiamato. Ma questo non è il punto. Sono ancora molto confuso circa l'utilità delle classi interne statiche in Java e la loro utilità o valore aggiunto.
Moldavo

316

Bene, Java ha "classi nidificate statiche", ma non sono affatto uguali alle classi statiche di C #, se è da lì che vieni. Una classe nidificata statica è solo una che non ha implicitamente un riferimento a un'istanza della classe esterna.

Le classi nidificate statiche possono avere metodi di istanza e metodi statici.

Non esiste una classe statica di primo livello in Java.


12
In Java Perché la classe nidificata statica consente i metodi di istanza? A che serve un metodo di istanza in una tale classe?
Geek,

19
@Geek: hai letto la mia risposta? Leggi attentamente la seconda frase. Perché non vorresti poter avere metodi di istanza di classi statiche? Puoi crearne istanze, dopo tutto.
Jon Skeet,

17
@Geek: Sì, è del tutto consentito. La tua "comprensione" che le classi statiche sono classi di utilità non è corretta, in pratica. Non è affatto ciò che significano le classi statiche in Java.
Jon Skeet,

14
@Geek: Sì. Esattamente come ho scritto nella mia risposta: "Una classe nidificata statica è solo una classe che non ha implicitamente un riferimento a un'istanza della classe esterna".
Jon Skeet,

6
@KhurramAli: Intendi implicitamente ? Non sono certamente esplicitamente statici, dato che non si usa la parola chiave staticper dichiararli. Sono implicitamente statici in quanto non è necessario un riferimento a nient'altro per costruirne uno. Personalmente trovo che la terminologia statica / non statica sia un po 'strana per le classi nidificate ... Penso che sarebbe più semplice parlare di quale sia il comportamento.
Jon Skeet,

157

Esiste una classe nidificata statica , questa classe [nidificata statica] non ha bisogno di un'istanza della classe che la racchiude per poter essere istanziata.

Queste classi [nidificate statiche] possono accedere solo ai membri statici della classe che racchiude [poiché non ha alcun riferimento alle istanze della classe che lo racchiude ...]

esempio di codice:

public class Test { 
  class A { } 
  static class B { }
  public static void main(String[] args) { 
    /*will fail - compilation error, you need an instance of Test to instantiate A*/
    A a = new A(); 
    /*will compile successfully, not instance of Test is needed to instantiate B */
    B b = new B(); 
  }
}

1
Quindi possiamo dire che possiamo usare le classi statiche interne per istanziarle senza la necessità di renderle pubbliche?
Moldavo

@moldovean Usiamo le classi statiche interne per istanziarle da un contesto statico (come main). Non penso che abbia nulla a che fare con la visibilità.
Michael Dorst,

2
@moldovean statico / non statico è ortogonale alla visibilità. Puoi avere qualsiasi tipo di visibilità sia statica che non statica. Il punto è che hai bisogno di un'istanza della classe che racchiude, al fine di creare quella interna?
Amit

103

Sì, esiste una classe nidificata statica in java. Quando si dichiara statica una classe nidificata, questa diventa automaticamente una classe autonoma che può essere istanziata senza dover istanziare la classe esterna a cui appartiene.

Esempio:

public class A
{

 public static class B
 {
 }
}

Poiché class Bè dichiarato statico, è possibile creare un'istanza esplicita come:

B b = new B();

Nota se class Bnon è stato dichiarato statico per renderlo autonomo, una chiamata all'oggetto di istanza sarebbe simile a questa:

A a= new A();
B b = a.new B();

7
si noti che è possibile creare un'istanza della classe non statica regolarmente, come B b = new B();se si provasse a creare un'istanza dalla classe Astessa.
Muhammed Refaat,

33

Cosa succede quando un membro all'interno di un classviene dichiarato come static..? È possibile accedere ai membri senza creare un'istanza di class. Pertanto, rendere la classe esterna (classe di livello superiore) staticnon ha significato. Pertanto non è permesso.

Ma puoi impostare le classi interne come statiche (in quanto è un membro della classe di livello superiore). Quindi è possibile accedere a quella classe senza creare un'istanza della classe di livello superiore. Considera il seguente esempio.

public class A {
    public static class B {

    }
}

Ora, all'interno di una classe diversa C, è Bpossibile accedere alla classe senza creare un'istanza di classe A.

public class C {
    A.B ab = new A.B();
}

staticanche le classi possono avere non-staticmembri. Solo la classe diventa statica.

Ma se la staticparola chiave viene rimossa dalla classe B, non è possibile accedervi direttamente senza creare un'istanza di A.

public class C {
    A a = new A();
    A.B ab = a. new B();
}

Ma non possiamo avere staticmembri all'interno di una non-staticclasse interiore.


Possiamo istanziare una classe statica o ha senso?
Supun Wijerathne,

6
Non come in altre lingue, staticha un solo significato in Java. Se qualcosa è staticin una classe significa che è possibile accedere a tale cosa senza creare un'istanza di quella classe. Non dice nulla riguardo alla creazione di istanze o meno.
Ramesh-X,

Spiacente StackOverflow! Non posso evitare di dire grazie Ramesh-X in questo caso! Hai coperto quasi tutto ciò che mi chiedevo riguardo alle classi interne statiche e alle classi interne.
Moldavo

Non puoi "impostare le classi interne come statiche". Questa è una contraddizione in termini . Una classe nidificata è interna o statica.
Marchese di Lorne,

13

Visto che questo è il miglior risultato su Google per "classe statica java" e la risposta migliore non è qui ho pensato di aggiungerlo. Sto interpretando la domanda di OP riguardo alle classi statiche in C #, che sono conosciute come singleton nel mondo Java. Per chi non lo sapesse, in C # la parola chiave "statica" può essere applicata a una dichiarazione di classe, il che significa che la classe risultante non può mai essere istanziata.

Estratto da "Effective Java - Second Edition" di Joshua Bloch (ampiamente considerata una delle migliori guide di stile Java disponibili):

A partire dalla versione 1.5, esiste un terzo approccio all'implementazione dei singoli. Crea semplicemente un tipo enum con un elemento:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}

Questo approccio è funzionalmente equivalente all'approccio di campo pubblico, tranne per il fatto che è più conciso, fornisce gratuitamente i macchinari di serializzazione e fornisce una garanzia coraggiosa contro l'istanza multipla, anche di fronte a sofisticati attacchi di serializzazione o di riflessione. Mentre questo approccio deve ancora essere ampiamente adottato, un tipo enum a elemento singolo è il modo migliore per implementare un singleton. (enfasi dell'autore)

Bloch, Joshua (2008-05-08). Efficace Java (serie Java) (p. 18). Pearson Education.

Penso che l'implementazione e la giustificazione siano piuttosto autoesplicative.


6
Un buon modo per implementare un Singleton. Sfortunatamente, la domanda non riguarda Singletons, si tratta di classi statiche
David SN

1
Java ha un'interpretazione piuttosto singolare della parola chiave "statica". Sembra che OP provenga da C # dove "classe statica" è l'equivalente di un singleton in Java. Ho aggiornato la mia risposta per chiarire questa interpretazione della domanda.
Bennet Huber,

1
La classe statica AC # non è un Singleton. Un'istanza Singleton è un oggetto e può implementare un'interfaccia il che significa che può partecipare all'iniezione di dipendenze e può essere derisa. La classe statica AC # non può implementare un'interfaccia o essere iniettata in alcun modo, ed è molto più vicina a un gruppo di funzioni C e ovviamente consente metodi di estensione.
Novaterata,

13

Una classe può essere statica in Java?

La risposta è , possiamo avere una classe statica in Java. In java, abbiamo variabili di istanza statiche , nonché metodi statici e anche blocco statico . Le classi possono anche essere rese statiche in Java.

In Java, non possiamo rendere statica la classe di livello superiore (esterna). Solo le classi nidificate possono essere statiche.

classe nidificata statica vs classe nidificata non statica

1) La classe statica nidificata non ha bisogno di un riferimento della classe esterna, ma la classe nidificata non statica o la classe interna richiede il riferimento della classe esterna.

2) La classe interna (o classe nidificata non statica) può accedere a membri statici e non statici della classe esterna. Una classe statica non può accedere a membri non statici della classe esterna. Può accedere solo ai membri statici della classe esterna.

vedi qui: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html


anche le classi interne "non statiche" non possono dichiarare campi o metodi statici
Mr.Cat


2

In termini semplici, Java supporta la dichiarazione di una classe come statica solo per le classi interne ma non per le classi di livello superiore.

classi di livello superiore: un progetto java può contenere più di una classe di livello superiore in ciascun file sorgente Java, una delle classi che prende il nome dal nome del file. Sono consentite solo tre opzioni o parole chiave di fronte alle classi di livello superiore, pubblica, astratta e finale .

Classi interne: le classi che fanno parte di una classe di livello superiore sono chiamate classi interne, che è fondamentalmente il concetto di classi nidificate. Le classi interne possono essere statiche . L'idea di rendere statiche le classi interne è quella di sfruttare l'istanza degli oggetti delle classi interne senza istanziare l'oggetto della classe di livello superiore. Questo è esattamente allo stesso modo in cui i metodi e le variabili statici funzionano all'interno di una classe di livello superiore.

Quindi Java supporta le classi statiche a livello di classe interna (nelle classi nidificate)

E Java non supporta le classi statiche alle classi di massimo livello.

Spero che questo dia una soluzione più semplice alla domanda per la comprensione di base delle classi statiche in Java.



0

Java ha metodi statici associati alle classi (ad esempio java.lang.Math ha solo metodi statici), ma la classe stessa non è statica.


0

Non è possibile utilizzare la parola chiave statica con una classe a meno che non sia una classe interna. Una classe interna statica è una classe nidificata che è un membro statico della classe esterna. È possibile accedervi senza creare un'istanza della classe esterna, utilizzando altri membri statici. Proprio come i membri statici, una classe nidificata statica non ha accesso alle variabili e ai metodi dell'istanza della classe esterna.

public class Outer {
   static class Nested_Demo {
      public void my_method() {
          System.out.println("This is my nested class");
      }
   }
public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();
      nested.my_method();
   }
}

Non è possibile utilizzare la staticparola chiave con una classe a meno che non sia una classe nidificata . "Statico interiore" è una contraddizione in termini .
Marchese di Lorne,

0

Un metodo statico significa che è possibile accedervi senza creare un oggetto della classe, a differenza di public:

public class MyClass {
   // Static method
   static void myStaticMethod() {
      System.out.println("Static methods can be called without creating objects");
   }

  // Public method
  public void myPublicMethod() {
      System.out.println("Public methods must be called by creating objects");
   }

  // Main method
  public static void main(String[ ] args) {
      myStaticMethod(); // Call the static method
    // myPublicMethod(); This would output an error

    MyClass myObj = new MyClass(); // Create an object of MyClass
    myObj.myPublicMethod(); // Call the public method
  }
}

Non risponde alla domanda
Marchese di Lorne,

-1

Tutte buone risposte, ma non ho visto un riferimento a java.util.Collections che utilizza tonnellate di classe interna statica per i loro metodi a fattore statico. Quindi aggiungendo lo stesso.

Aggiunta di un esempio da java.util.Collections che ha più classi interne statiche. Le classi interne sono utili per raggruppare il codice a cui è necessario accedere tramite una classe esterna.

/**
 * @serial include
 */
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                             implements Set<E>, Serializable {
    private static final long serialVersionUID = -9215047833775013803L;

    UnmodifiableSet(Set<? extends E> s)     {super(s);}
    public boolean equals(Object o) {return o == this || c.equals(o);}
    public int hashCode()           {return c.hashCode();}
}

Ecco il metodo del fattore statico nella classe java.util.Collections

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
    return new UnmodifiableSet<>(s);
}


Non hai ricevuto il tuo commento? Puoi elaborare? Sto cercando di capire il tuo commento.
Jay Rajput,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.