2015-05-27 18 views
16

Vorrei sapere se si dispone di una classe con solo metodi statici, un'istanza effettiva della classe viene creata da qualche parte quando si chiama 1st static metodo?Un'istanza di una classe creata automaticamente quando si chiama per la prima volta un metodo statico

Questo è un po 'di confusione da comprendere in termini di gestione della memoria come non si chiama mai effettivamente il costruttore o si crea un'istanza del metodo in modo esplicito.

Se un'istanza viene creata, mi piacerebbe capire meglio dove questa istanza vive e per quanto tempo.

+6

Si sta confondendo il caricamento della classe (che crea oggetti 'Class' e vari metadati specifici della VM) con l'istanza dell'oggetto. (Si noti che le classi astratte possono avere metodi statici - nessuna istanza automagica nascosta sarebbe possibile.) –

risposta

13

No. chiamata di un metodo static non richiede (o creare) un'istanza di un class. Vedi anche JLS-8.4.3.2 static methods che dice (in parte)

Un metodo dichiarato static viene chiamato un metodo di classe.

...

Procedimento classe è sempre invocato senza riferimento ad un particolare oggetto.

+2

Grazie a questo aiuto.Una domanda parallela, diciamo che si crea una classe anonima all'interno di un metodo statico, che cosa succede al riferimento genitore assegnato alla classe anonima (come per impostazione predefinita nelle classi java anonime e interne si ottiene un riferimento forte all'oggetto che lo racchiude)? – AlexVPerl

+2

Immagino tu intenda una classe anonima [JLS-15.9.5] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5). Il JLS dice (in parte) * una classe anonima è sempre una classe interiore (§8.1.3); non è mai statico (§8.1.1, §8.5.1). Indipendentemente da ciò, alla fine dell'invocazione del metodo esso non rientra nello scope (a meno che non sia assegnato a un diverso, 'static', riferimento). –

+3

@AlexVPerl non esiste alcun oggetto che racchiude e le classi anonime nei metodi statici non hanno riferimenti principali. –

4

I metodi static appartengono alla classe, non al riferimento dell'oggetto. È possibile chiamare il metodo static e dimenticare di sprecare memoria durante la creazione di un riferimento all'oggetto della classe utilizzata, che non si verifica. Quando si chiama un metodo static su un riferimento a un oggetto, viene visualizzato un avviso del compilatore sull'oggetto. È anche possibile chiamare i metodi static su una variabile della classe desiderata e questa variabile può essere null, il metodo static verrà richiamato senza problemi.

public class Foo { 
    public static void sayHello(String name) { 
     System.out.println("Hello " + name); 
    } 
} 

//works, no instance of Foo was created 
Foo.sayHello("AlexVPerl"); 
Foo foo = new Foo(); 
//works, compiler raises a warning here 
foo.sayHello("AlexVPerl"); 
foo = null; 
//works, compiler raises a warning here 
//and as you can see, it doesn't matter if the instance is null 
foo.sayHello("AlexVPerl"); 
6

Diciamo che avete

static class Foo 
{ 
    static Bar bar = new Bar(); 

    static int func(){ ... } 
} 

ovviamente, un oggetto Foo non verrà creato per chiamare func().

Tuttavia, la classe Foo deve essere caricata in memoria; e all'applicazione, esiste un oggetto corrispondente alla classe, che può essere indicato come Foo.class o Class.forName("Foo").

Una classe caricata non è ancora stata inizializzata. Quando si chiama un metodo statico per la prima volta, la classe viene inizializzata; alcuni "spazi" sono allocati per variabili statiche e viene eseguito il codice di inizializzazione statico (come new Bar()).

Questo "spazio" non è visibile all'applicazione come oggetto; ma è anche una struttura di dati in memoria che riguarda le garbage collection (e altri oggetti a cui fa riferimento, come bar)

La classe e lo "spazio" sono idonei per GC solo quando il classloader che ha caricato la classe è idoneo per GC. Per le normali applicazioni da riga di comando, ciò non accade mai. Ma per molte altre applicazioni, la classe GC è importante e il caricamento di classe deve essere fatto con attenzione.

+2

A meno che non sia stato modificato in Java 8, la "classe statica" non ha senso in Java a meno che non si tratti di una classe nidificata. –