web-dev-qa-db-fra.com

Quelle est la différence entre la variable objet non initialisée et la variable objet initialisée à null dans Java

J'ai les deux variables d'objet suivantes

Date a;
Date b=null;

Certainement, 'a' et 'b' ne font référence à aucun objet.

Maintenant, si j'invoque la déclaration suivante

System.out.println(a.toString());

Il y aura une erreur de compilation, alors que si j'appelle la déclaration suivante

System.out.println(b.toString());

Il n'y aura pas d'erreur de compilation mais il y aura une erreur d'exécution. Quelle en est la raison et quelle valeur sera réellement stockée dans "b" pour représenter une valeur nulle?

12
Harish_N

C'est parce que l'état des variables locales est contrôlé dans sa portée

 // method/loop/if/try-catch etc...
 {
   Date d; // if it's not intialised in this scope then its not intialised  anywhere
 }

Ce qui n'est pas le cas pour les champs

class Foo{
 Date d; // it could be intialised anywhere, so its out of control and Java will set to null for you
}

Maintenant, pourquoi son amende pour définir une variable à null et l'utiliser immédiatement? c'est peut-être une erreur historique qui mène parfois à des erreurs horribles

 {
  Date d = null;
  try{
  }catch{ // hide it here 
  }
  return d;
 } 

Maintenant, quelle est la différence sémantique?

Date d;

déclare simplement une variable qui peut contenir une référence qui pointe vers un objet de type Date, cependant

Date d= null; 

fait exactement la même chose mais la référence pointe cette fois sur null, null est comme n'importe quelle référence, il prend un espace d'un pointeur natif, c'est-à-dire 4 octets sur les machines 32 bits et 8 octets sur les machines 64 bits

3
Sleiman Jneidi

Il n'y a aucune différence pour les champs de classe. Ils sont null par défaut pour les objets, 0 pour les valeurs numériques et false pour les booléens.

Pour les variables déclarées dans les méthodes - Java nécessite leur initialisation. Ne pas les initialiser provoque une erreur de temps de compilation lors de leur accès.

Quelle est la raison? Les champs de classe peuvent être modifiés par n'importe quelle méthode. Dans n'importe quel ordre, la méthode est invoquée. Tous les champs non privés peuvent être modifiés par d'autres classes et/ou classes étendant cette classe. Par conséquent, il est inutile de notifier une variable non initialisée, car elle peut être affectée à de très nombreux endroits.

Cependant, les variables à l'intérieur des méthodes sont locales et ne peuvent être modifiées qu'à l'intérieur de la méthode elle-même. Il est donc à la fois possible et rationnel de signaler d'éventuelles erreurs. Et le compilateur essaie de le faire. S'il sait le champ n'est pas initialisé, il affichera une erreur, car ce n'est jamais ce que vous voulez. Si ce n'est pas sûr - cela donnera un avertissement, afin que vous puissiez vous en assurer.

public static class Test {
    Date a; // ok 
    Date b = null; // ok

    public void test() {
        Date c;
        Date d = null;

        System.out.println(a.toString());
        System.out.println(b.toString());
        System.out.println(c.toString()); // error
        System.out.println(d.toString()); // warning
    }
}
19
Dariusz