web-dev-qa-db-fra.com

Uninitialized int vs Integer

J'étais en train d'étudier mon Java pour me préparer à un examen et j'ai rencontré une sorte de problème avec les valeurs int/Integer non initialisées.

class A
    {
       int x;
       Integer y;
       static int z;
       static Integer z2;
       public A(){}   
    }

Disons que j'initialise un objet de la classe A. A a = new A ();

J'ai essayé cela dans un compilateur et j'ai obtenu les résultats 

a.x == 0; true
a.x == null; Static Error: Bad type in comparison expression
a.y == 0; Java.lang.NullPointerException
a.y == null; true
a.z == 0; true 
a.z == null; Static Error: Bad type in comparison expression
a.z2 == 0; NullPointerException
a.z2 == null; true

De plus, j'ai essayé d'autres comparaisons int/Interger non initialisées dans un volet d'interactions pour voir si j'obtiendrais des résultats différents si mes x, y n'étaient pas des variables d'instance de classe comme ci-dessus.

int x;
Integer y;
x == 0; true
x == null; Static Error: Bad type in comparison expression
y == 0; Java.lang.NullPointerException
y == null; true

Cependant, mon professeur affirme dans une conférence que les valeurs devraient être les suivantes:

x == 0; Uninitialized
x == null; Undefined
y == 0; Java.lang.NullPointerException
y == null; Uninitialized

Maintenant, je ne veux pas douter de l'auteur de l'examen, mais quelle valeur de vérité x == 0 et y == est correcte? Une explication sur pourquoi serait très appréciée, merci.

19
Kevin Zhou
  • a.x == 0 - Vrai parce que a.x a une valeur par défaut de 0.
  • a.x == null - Comme indiqué, il s'agit d'une erreur de compilation. Ceci découle de §15.21.3 : "Une erreur de compilation survient s'il est impossible de convertir le type de l'un des opérandes en un autre type par une conversion de conversion (§5.5)." Le type null n'est pas convertible en nombre.
  • a.y == 0 - Ceci essaie de décompresser a.y, qui est null, donc il lève une exception NullPointerException. Contrairement à ce qui précède (qui a un null littéral), le compilateur n'essaie pas de comprendre au moment de la compilation que a.y sera nul.
  • a.y == null - Encore une fois, true car a.y est initialisé à null
  • a.z == 0 - Identique à a.x (sauf statique)
  • a.z == null - Identique à a.x (sauf statique)
  • a.z2 == 0 - Identique à a.y (sauf statique)
  • a.z2 == null - Identique à a.y (sauf statique)

Le problème avec le volet d'interactions est que c'est le IDE comment le mettre en œuvre. Si x et y sont des variables locales (non initialisées), la compilation des quatre dernières comparaisons échouera.

18
Matthew Flaschen

Les valeurs Java de types simples tels que int/long ne peuvent pas être null et sont donc initialisées par 0.

17
Stan Kurilin

En Java, les variables de classe (statiques), les variables d'instance (celles de votre exemple) et les composants de tableau reçoivent des valeurs par défaut. D'autre part, les variables locales doivent recevoir des valeurs explicitement et ne reçoivent pas les valeurs par défaut.

Pour plus de détails, voir §4.12.5 .

10
Nabb
int x;
Integer y;
x == 0; true. because x is initialized to 0 by JVM
x == null; Static Error: Bad type in comparison expression
y == 0; Java.lang.NullPointerException
y == null; true, because y is uninitialized
2
Ishtar
class A
{
   int x;
   Integer y;
   static int z;
   static Integer z2;
   public A(){}   
}

votre compilateur dit

x == 0; true;
x == null; Static Error: Bad type in comparison expression
y == 0; Java.lang.NullPointerException
y == null; true

ton professeur dit

x == 0; Uninitialized
x == null; Undefined
y == 0; Java.lang.NullPointerException
y == null; Uninitialized

Les deux sont corrects, sauf que votre enseignant utilise des termes différents. La raison en est que par défaut, Java initialise les valeurs non initialisées à 0 ou à zéro pour les objets. Votre enseignant se réfère à eux comme non initialisé. Il a raison car ces valeurs n'ont pas encore été initialisées (mais elles ont toujours des valeurs par défaut). Votre enseignant veut vous apprendre à toujours initialiser vos variables car c'est une bonne pratique. 

2
vincent456

EDIT: les variables locales non initialisées ne peuvent pas être utilisées.

Outre les habitants:

Unitialized int est égal à 0.

Unitialized Integer est égal à null.

Entier est un objet. Les objets unitialisés sont égaux à null. 

int est un type primitif. Les spécifications de langue définissent sa valeur non initialisée à 0.

1
pablosaraiva

Celui-ci m'a déjà dérangé car les descriptions et le comportement semblent un peu incohérents. Si vous examinez la spécification du langage dans section 4.12.5 , il existe une section qui décrit cela et qui correspond à ce que vous avez observé le compilateur. 

La raison pour laquelle je pense que cela est parfois déroutant est que d'autres publications que j'ai lues dans Sun ("Core Java 2" par exemple) décrivent le comportement indiqué par votre professeur. Et dans une autre variante, j'utilise NetBeans qui permet l'utilisation de primitives non initialisées mais signale l'utilisation d'objets non initialisés. Je ne suis cependant pas sûr qu'il s'agisse d'un compilateur ou d'un choix IDE. 

[EDIT: après avoir examiné l’un des articles, je pense que cette confusion découle du comportement différent des variables locales par rapport aux champs.]

1
JeffW

Tous les objets/variables d'une classe sont initialisés aux valeurs par défaut lorsqu'un objet est instancié.

C’est la raison pour laquelle les variables de la classe ont les valeurs suivantes:

int x = 0 //default value (value type)
Integer y = null //default values of any object; here Integer is reference type

... et le reste continue de la même manière. J'espère que ma réponse est utile !!!

0
GuruC

Cette question a été posée il y a quelque temps et des réponses correctes ont été apportées, mais j'estime qu'elles peuvent être quelque peu élargies.

J'aimerais citer quelques lignes de la page officielle des didacticiels. https://docs.Oracle.com/javase/tutorial/Java/nutsandbolts/datatypes.html

Les champs déclarés mais non initialisés seront définis par défaut par le compilateur.

Les variables locales sont légèrement différentes. le compilateur n'affecte jamais une valeur par défaut à une variable locale non initialisée. L'accès à une variable locale non initialisée entraînera une erreur lors de la compilation.

En Java, les primitives ont une valeur qui est un nombre. (Ce n'est pas aussi simple et je vous encourage vivement à en lire plus à ce sujet.) Une valeur pour un objet est une référence à partir de laquelle il est possible de trouver le contenu de l'objet.

La valeur par défaut d'une primitive est essentiellement 0, la valeur par défaut d'un objet étant null. (quand non initialisé et quand un champ)

Dans votre exemple, vous essayez de comparer "0 à 0, null à null et null à 0".

Le fait est: null! = 0.

  • 0 = une valeur numérique ne représentant rien.
  • null = littéral pour représenter une référence non existante. (vous pouvez voir Qu'est-ce qui est null en Java? pour plus de détails sur null)

FYI: Je pense que Matthew Flaschen a déjà répondu à cette question, je voulais simplement ajouter des informations supplémentaires pour ceux qui sont intéressés.

0
Atspulgs