java - Come mai invocare un metodo(statico)su un riferimento null non genera NullPointerException?





(5)


I metodi statici non hanno bisogno di un riferimento all'oggetto. Quindi puoi chiamarlo anche il riferimento all'oggetto è nullo. Ecco come funziona il metodo principale.

Prova a rimuovere la designazione statica dall'oggetto per vedere l'eccezione del puntatore nullo.

Ho scritto questo programma in Java

public class Why {

  public static void test() {
    System.out.println("Passed");
  }

  public static void main(String[] args) {
    Why NULL = null;
    NULL.test();
  }

}

Ho letto che invocare un metodo su un oggetto null provoca NullPointerException , eppure il programma di cui sopra non lo fa? Perchè è questo? Non capisco qualcosa correttamente?




test() è un metodo static . Un membro static appartiene al tipo e non richiede l'accesso a un'istanza.

Un membro static dovrebbe essere accessibile SOLO tramite un'espressione di tipo. Cioè, dovresti averlo scritto come segue:

Why.test(); // always invoke static method on the type it belongs to!

Java consente di accedere a un membro static tramite un'espressione di riferimento oggetto, ma questo è MOLTO fuorviante, poiché questa NON è la semantica effettiva di un accesso static membri.

Why aNull = null; 
aNull.test(); // DO NOT EVER DO THIS!
// invokes Why.test(), does NOT throw NullPointerException

Quando si accede a un membro static tramite un'espressione di riferimento oggetto, solo il tipo dichiarato del riferimento è importante. Ciò significa che:

  • Non importa se il riferimento è effettivamente null , poiché non è richiesta alcuna istanza
  • Se il riferimento non è null , non importa quale sia il tipo di runtime dell'oggetto, non vi è alcuna spedizione dinamica !!!

Come puoi vedere, gli opposti esatti sono veri su entrambi i punti, ad esempio l'accesso ai membri. Questo è il motivo per cui static membri static non dovrebbero MAI essere accessibili in un modo "non static ", perché dà un aspetto molto fuorviante su ciò che effettivamente sta facendo.

Domande correlate




Dovresti attivare i vari avvisi nel tuo IDE. È probabile che vedrete un avvertimento sull'accesso a un membro statico in modo non statico.

Si potrebbe fare qualcosa come (Why) (null) .test (), è solo usando il (Why) (null) per ottenere la classe.




È un metodo statico, che ti permette di chiamare metodi su di esso senza istanziare un'istanza.




L'override del metodo è reso possibile dall'invio dinamico , il che significa che il tipo dichiarato di un oggetto non determina il suo comportamento, ma piuttosto il suo tipo di runtime:

Animal lassie = new Dog();
lassie.speak(); // outputs "woof!"
Animal kermit = new Frog();
kermit.speak(); // outputs "ribbit!"

Anche se sia lassie che kermit sono dichiarati come oggetti di tipo Animal , il loro comportamento (metodo .speak() ) varia perché l'invio dinamico bind solo il metodo .speak() a un'implementazione in fase di esecuzione - non al momento della compilazione.

Ora, ecco dove la parola chiave static inizia ad avere un senso: la parola "statico" è un antonimo per "dinamico". Quindi il motivo per cui non è possibile sovrascrivere i metodi statici è perché non ci sono dispatch dinamici sui membri statici - perché static significa letteralmente "non dinamico". Se spedivano dinamicamente (e quindi potevano essere cancellati) la parola chiave static non avrebbe più senso.





java static null nullpointerexception