Qual è la ragione per cui “il metodo non statico non può essere referenziato da un contesto statico”?

L’errore principiante molto comune è quando si tenta di utilizzare una proprietà di class “staticamente” senza creare un’istanza di quella class. Ti lascia con il messaggio di errore citato:

È ansible rendere statico il metodo non statico o creare un’istanza di tale class per utilizzare le sue proprietà.

Perché? Non sto chiedendo soluzioni. Sarei grato di sapere qual è la ragione che ci sta dietro. La vera ragione!

private java.util.List someMethod(){ /* Some Code */ return someList; } public static void main(String[] strArgs){ // The following statement causes the error. You know why.. java.util.List someList = someMethod(); } 

Non puoi chiamare qualcosa che non esiste. Dato che non hai creato un object, il metodo non statico non esiste ancora. Un metodo statico (per definizione) esiste sempre.

Il metodo che stai tentando di chiamare è un metodo a livello di istanza; non hai un’istanza.

static metodi static appartengono alla class, static metodi non static appartengono alle istanze della class.

L’essenza della programmazione orientata agli oggetti è la logica incapsulante insieme ai dati su cui opera.

I metodi di istanza sono la logica, i campi di istanza sono i dati. Insieme formano un object.

 public class Foo { private String foo; public Foo(String foo){ this.foo = foo; } public getFoo(){ return this.foo; } public static void main(String[] args){ System.out.println( getFoo() ); } } 

Quale potrebbe essere il risultato dell’esecuzione del programma di cui sopra?

Senza un object, non ci sono dati di istanza e mentre i metodi di istanza esistono come parte della definizione di class, hanno bisogno di un’istanza di object per fornire i dati per loro.

In teoria, un metodo di istanza che non accede a nessun dato di istanza potrebbe funzionare in un contesto statico, ma in realtà non esiste alcun motivo per cui sia un metodo di istanza. È una decisione di progettazione linguistica di consentirlo comunque piuttosto che creare una regola aggiuntiva per vietarlo.

Ho appena realizzato, penso che le persone non dovrebbero essere esposte al concetto di “statico” molto presto.

I metodi statici dovrebbero probabilmente essere l’eccezione piuttosto che la norma. Soprattutto all’inizio se vuoi imparare OOP. (Perché iniziare con un’eccezione alla regola?) Questo è molto contro-pedagogico di Java, che la “prima” cosa che dovresti imparare è la cosa principale vuota statica pubblica. (Poche applicazioni Java reali hanno comunque i loro metodi principali.)

Penso che valga la pena sottolineare che con le regole del linguaggio Java il compilatore Java inserisce l’equivalente di “questo”. quando nota che stai accedendo ai metodi di istanza o ai campi di istanza senza un’istanza esplicita. Naturalmente, il compilatore sa che può farlo solo all’interno di un metodo di istanza, che ha una “questa” variabile, come i metodi statici no.

Ciò significa che quando ti trovi in ​​un metodo di istanza, i seguenti sono equivalenti:

 instanceMethod(); this.instanceMethod(); 

e questi sono anche equivalenti:

 ... = instanceField; ... = this.instanceField; 

Il compilatore sta effettivamente inserendo il “questo”. quando non si fornisce un’istanza specifica.

Questo bit di “aiuto magico” del compilatore può confondere i novizi: significa che le chiamate di istanza e le chiamate statiche a volte sembrano avere la stessa syntax mentre in realtà sono chiamate di diversi tipi e meccanismi sottostanti.

La chiamata al metodo di istanza viene talvolta definita invocazione o invio di metodo a causa dei comportamenti dei metodi virtuali che supportano il polimorfismo; il comportamento di dispatch avviene indipendentemente dal fatto che tu abbia scritto un’istanza dell’object esplicita da usare o che il compilatore abbia inserito un “this”.

Il meccanismo di chiamata del metodo statico è più semplice, come una chiamata di funzione in un linguaggio non OOP.

Personalmente, penso che il messaggio di errore sia fuorviante, potrebbe leggere “il metodo non statico non può essere referenziato da un contesto statico senza specificare un’istanza dell’object esplicita “.


Ciò di cui il compilatore si lamenta è che non può semplicemente inserire lo standard “questo”. come avviene nei metodi di istanza, poiché questo codice si trova all’interno di un metodo statico; tuttavia, forse l’autore si è semplicemente dimenticato di fornire l’istanza di interesse per questa invocazione, ad esempio un’istanza fornita al metodo statico come parametro o creata all’interno di questo metodo statico.

In breve, è ansible chiamare i metodi di istanza all’interno di un metodo statico, è sufficiente disporre e specificare un object istanza esplicito per l’invocazione.

Le risposte finora descrivono perché, ma qui c’è qualcos’altro che potresti voler considerare:

Puoi chiamare un metodo da una class instantiable aggiungendo una chiamata al metodo al suo costruttore,

 Object instance = new Constuctor().methodCall(); 

o

 primitive name = new Constuctor().methodCall(); 

Questo è utile se si desidera utilizzare un metodo di una class istantiable solo in un singolo ambito. Se si chiamano più metodi da una class instantiable in un singolo ambito, creare sicuramente un’istanza referente.

Se proviamo ad accedere ad un metodo di istanza da un contesto statico, il compilatore non ha modo di indovinare quale metodo di istanza (variabile per quale object), ci si sta riferendo a. Però, puoi sempre accedervi usando un riferimento a un object.

Il compilatore aggiunge effettivamente un argomento ai metodi non statici. Aggiunge un this pointer/reference. This is also the reason why a static method can not use this this pointer/reference. This is also the reason why a static method can not use this , perché non c’è alcun object.

Un metodo statico collega un’azione ad un tipo di object, mentre il metodo non statico collega un’azione ad un’istanza di quel tipo di object. Tipicamente è un metodo che fa qualcosa in relazione all’istanza.

Ex:

l’auto di class potrebbe avere un metodo di lavaggio, che indicherebbe il lavaggio di una macchina particolare, mentre un metodo statico si applicherebbe al tipo di auto.

se un metodo non è statico, “dice” al compilatore che il metodo richiede l’accesso ai dati a livello di istanza nella class, (come un campo non statico). Questi dati non sarebbero disponibili a meno che non sia stata creata un’istanza della class. Quindi il compilatore genera un errore se si tenta di chiamare il metodo da un metodo statico. Se infatti il ​​metodo NON fa riferimento a membri non statici della class, rendere il metodo statico.

In Resharper, ad esempio, la semplice creazione di un metodo non statico che NON fa riferimento a nessun membro statico della class genera un messaggio di avviso “Questo metodo può essere reso statico”

La semplice ragione alla base di questo è che è ansible accedere ai dati statici dei membri della class genitore (solo se non sono sovrascritti) ma per i membri o metodi di dati (non statici) abbiamo bisogno del loro riferimento e quindi possono essere chiamati solo attraverso un object .

Quindi stai chiedendo una ragione molto centrale?

Bene, dal momento che stai sviluppando in Java, il compilatore genera un codice object che la Java Virtual Machine può interpretare. La JVM è comunque un programma binario eseguito in linguaggio macchina (probabilmente la versione della JVM specifica per il tuo sistema operativo e l’hardware è stato precedentemente compilato da un altro linguaggio di programmazione come C per ottenere un codice macchina che può essere eseguito nel tuo processore). Alla fine, qualsiasi codice viene tradotto in codice macchina. Quindi, creare un object (un’istanza di una class) equivale a riservare uno spazio di memoria (registri di memoria che saranno registri del processore quando lo scheduler della CPU del sistema operativo mette il programma in cima alla coda per eseguirlo) avere un luogo di archiviazione dei dati che può essere in grado di leggere e scrivere dati. Se non si dispone di un’istanza di una class (che si verifica in un contesto statico), allora non si dispone di quello spazio di memoria per leggere o scrivere i dati. In effetti, come altre persone avevano detto, i dati non esistono (perché dall’inizio non hai mai scritto né prenotato lo spazio di memoria per archiviarlo).

Mi scusi per il mio inglese! Sono latino!

Un metodo non statico dipende dall’object. Viene riconosciuto dal programma una volta creato l’object.

I metodi statici possono essere chiamati anche prima della creazione di un object. I metodi statici sono ottimi per fare confronti o operazioni che non dipendono dagli oggetti reali con cui si pianifica di lavorare.