Null est-il un objet?


119

Est-ce que null est un Objecten Java?


41
Non ce n'est pas le cas, et pour ceux qui se demandent pourquoi une telle question, il existe des langages où null est en effet un objet comme les autres, par exemple Ruby.
JRL

7
Dans Scala, qui est très méticuleux sur les types, il y a un type Null(un trait , en fait) ayant une seule instance null.
Carl Smotricz

1
@JRL: Juste par curiosité, je me demande comment cela influence le fonctionnement de JRuby ... (je ne connais pas assez ce niveau d'implémentation pour le savoir avec certitude.)
Benjamin Oakes

Pour ajouter au commentaire de @ JRL - L'équivalent approximatif de Ruby à nullis nil, qui est une instance de NilClass
Eliot Sykes

Ou javascript, dans lequel null instanceof Objectest faux mais typeof(null)retourne 'object'. Est-ce un objet dans ce cas? Qui sait.
Don Hatch

Réponses:


166

Si null était un objet, il prendrait en charge les méthodes java.lang.Objecttelles que equals(). Cependant, ce n'est pas le cas - toute invocation de méthode sur un null entraîne un NullPointerException.

Et voici ce que la spécification du langage Java a à dire sur ce sujet:

Il existe également un type nul spécial, le type de l'expression null, qui n'a pas de nom. Étant donné que le type nul n'a pas de nom, il est impossible de déclarer une variable de type nul ou de convertir en type nul. La référence null est la seule valeur possible d'une expression de type nul. La référence null peut toujours être convertie en n'importe quel type de référence. En pratique, le programmeur peut ignorer le type nul et prétendre simplement que null est simplement un littéral spécial qui peut être de n'importe quel type de référence.

Je pense que cela peut se résumer à "nul est spécial".


1
Ainsi, un objet en Java n'est un objet que s'il est égal à ou à des sous-classes java.lang.Object. Pratiquement - oui. Vous ne pouvez pas créer une classe qui n'est pas une sous-classe de java.lang.Object, mais je n'y ai jamais pensé d'un point de vue plus philosophique
Andreas Dolk

Curieusement, de toutes choses, la doc deNullPointerException l' API pour fait mention d'un » nullobjet«… :) Mais alors, c'était aussi correct de parler de »pointeurs nuls«…
Lumi

Vous avez dit: "La référence nulle peut toujours être convertie en n'importe quel type de référence". Alors, pouvons-nous retourner null (typé-si autorisé) dans une méthode avec un type de référence d'objet (retour)?
Srichakradhar

1
@Srichakradhar: oui, nous pouvons! Ce que vous pouvez découvrir plus facilement en l'essayant dans le code qu'en le demandant ici.
Michael Borgwardt

1
"La référence null est la seule valeur possible d'une expression de type nul". Il est temps de lire le document Spécifications. :)
sofs1

32

Selon la spécification Java , nullest un type qui peut être affecté à une variable d'objet (sous forme de valeur comme indiqué dans le commentaire). Cependant, vous ne pouvez pas instancier ou créer des variables de ce type, vous devez utiliser le littéral nullfourni par le compilateur.


8
null est un type et une valeur.
Joachim Sauer

5
Le nullnom est une "instance" du nulltype, apparemment.
strager

nulln'est pas une variable, c'est un littéral: JLS, 3.10.7. The Null Literal
Gerold Broser

Re " nullest un type qui peut être attribué ": 1) null(dans le code) est le littéral nul , pas le type nul 2) Les types ne peuvent pas être affectés à des variables en Java en général, voir JLS 4.1: " Il y a [... ] deux types de valeurs de données qui peuvent être stockées dans des variables [...]: les valeurs primitives (§4.2) et les valeurs de référence (§4.3). " C'est la référence nulle qui peut être affectée via le nulllittéral. ... suite ...
Gerold Broser

3) objet dans " variable objet ", par rapport à la variable de classe, ne fait généralement pas référence au type mais à la durée de vie. Lorsqu'on fait référence au type, on l'appelle généralement variable d'un type de référence ou, pour faire court, variable de référence (type). Je connais 4 types dans l'API Java qui exposent des variables d'instance / objet (il peut y en avoir plus): des tableaux avec seslength et les sous-classes de java.awt.geom.Point2D.
Gerold Broser

28

Absolument pas: null instanceof Objectrenvoie false.


17
Et pourtant, c'est une affectation compatible avec tous les types de référence.
Chris Vest


12

Null est l'absence d'objet.


Mais le type nul est attribuable à chaque type de référence.
Tom Hawtin - tackline

Il n'y a pas de "type nul"; null est une valeur spécifique d'expressions non primitives (c'est-à-dire des références; il n'y a pas non plus de "type de référence" en Java, à ma connaissance).
Tommy McGuire

3
Tommy: JLS 4.1: "Il existe également un type nul spécial, le type de l'expression null, qui n'a pas de nom."
Ken


12

JRL a écrit:

Non ce n'est pas, ...

Comme souvent, cela dépend d'où vous le regardez, de qui vous croyez le plus.

Selon le JLS, oui, c'est le cas . Surtout si vous reformulez la question comme suit: «Le nulllittéral est-il de type Object?». En plus de JLS 4.1 cité par Michael Borgwardt ci-dessus:

Voir JLS 3.10.7 :

Un littéral nul est toujours de type nul.

et JLS 4.10 :

Les sous-types d'un type T sont tous les types U tels que T est un supertype de U, et le type nul.

ou JLS 4.10.2 :

Les supertypes directs du type nul sont tous des types de référence autres que le type nul lui-même.

[Souligné par moi.]

Selon le compilateur d'Eclipse 2019-09, ce n'est pas :

true.toString();  // Cannot invoke toString() on the primitive type boolean
null.toString();  // Cannot invoke toString() on the primitive type null

Selon OpenJDKs 12.0.1, javac c'est :

true.toString();  // error: boolean cannot be dereferenced
null.toString();  // error: <null> cannot be dereferenced

Où les chevrons impliquent qu'il nulls'agit d'un type autre que primitif. Et selon JLS 4.1 :

Il existe deux types de types dans le langage de programmation Java: les types primitifs (...) et les types de référence (...).

si ce n'est pas l'un c'est l'autre.


Claudiu a écrit:

null est un peu moche.

Au contraire, nullc'est beau. Que suggéreriez-vous plutôt comme valeur par défaut pour une variable de type référence? Une combinaison de bits arbitraire? Bienvenue à la violation d'accès ou, pire encore, à l'enfer du pointeur!


Joachim Sauer a écrit:

null est un type et une valeur.

Il y a en fait trois éléments en conjonction avec null (voir aussi JLS 3.10.7 ):

  1. Le type nul (autrement sans nom) .
  2. Le null littéral .
  3. La valeur de référence nulle . (Communément abrégé en valeur nulle ou simplement null .)

(1) Notez que, selon JLS 4.10.2 cité ci-dessus, le type nul utilise l'héritage multiple non seulement pour les interfaces mais aussi pour les classes. Ce que nous savons tous n'est pas possible pour nous, les programmeurs d'applications.

(2) Le littéral nul pourrait être imaginé comme une variable définie comme:

JVM_global final null_type null = new null_type();

Notez également JLS 3.9 :

Une variété de séquences de caractères est parfois considérée, à tort, comme des mots-clés:

  • nulln'est pas un mot-clé, mais plutôt le littéral nul ( §3.10.7 ).

Concernant null instanceof <any type>

Avec JLS 4.10.2 à l'esprit («le type nul est un sous-type de chaque type») null instanceof <any type>devrait être supposé être évalué true, n'est-ce pas? À première vue, oui, mais JLS 15.20.2 donne la réponse insight:

[...] le résultat de l' instanceofopérateur est truesi la valeur de RelationalExpression n'est pasnull [...]. Sinon, le résultat estfalse .

[Souligné par moi.]

Demandez-vous ce qui a le plus de sens (du point de vue d'un programmeur d'application):

  • Donner falseet donc indiquer qu'une expression de référence n'est pas d'un type qui nous est exposé, c'est-à-dire indiquer qu'elle ne fait référence à rien d'utile pour nous

  • ou donner true, nous informant ainsi que l'expression évalue à une référence spéciale, la référence nulle , référençant un "objet" dont nous ne savons même pas s'il existe et qui est du type nul spécial qui n'a pas de nom, n'est pas exposé à us mais via le littéral nul , est-ce qu'un sous-type de n'importe quel type incluant l'héritage multiple et doit être ignoré de toute façon? Prenons également l'exemple le plus pratique:

     class Car implements Vehicle {  
     ...
     Vehicle car = null;
     ...
     boolean b = car instanceof Car;  // True? There's not even an instance
     ...                              // which could be of type Car.

Ce qui conduit également à:

Pourquoi n'est-ce instanceofpas une bonne façon de dire quelque chose à propos nullde l'objet de s?

Ça ne s'appelle instanceofpas sameorsubtypeof. Cela signifie que nous comparons le type d'une instance avec un type, pas deux types. Cela nullsignifie maintenant : «Il n'y a pas d'instance» et s'il n'y a pas d'instance, il n'y a pas de type d'instance. Il est évident que ne rien comparer à quelque chose est censé mener false.

Ou dans un exemple du monde réel "plus":

  • J'ai entre les mains une photo en taille réelle d'une pomme ( = type de référence ) avec »Big Apple« ( = nom du type de référence ) écrit dessus.
  • Il y a une table ( = tas ) devant moi.
  • S'il y a une pomme ( = instance ) sur la table, un cordon ( = référence ) y est connecté.
  • Je tiens l'autre extrémité de ce cordon dans ma main ( = variable de référence ).
  • Je trace la pomme le long du cordon et la compare avec ma photo ( = instanceof ).
  • Si la pomme est de la même taille ou plus grande que l'image, l'écriture «Big Apple» lui s'applique ( = vrai ).
  • S'il est plus petit, alors non ( = faux ).
  • S'il n'y a pas de pomme sur la table (= aucune instance ) et, par conséquent, aucun cordon n'existe ( = null ) l'écriture ne s'applique pas non plus ( = false ). Parce que: Aucune pomme n'est-elle une grosse pomme? Non ce n'est pas.


Comme le résume Michael: "nul est spécial" en effet.


2
Apple et nul? N'avez-vous pas peur d'un procès? :)
Gábor Lipták

9

Non, ce n'est pas une instance d'une classe ni d'une classe. C'est une référence à rien.

Edit : je n'ai pas lu les spécifications, donc ce qui précède peut ne pas être précis à 100%.


5

Comme expliqué dans le chapitre 4.1 Les types de types et les valeurs de la spécification du langage Java, null est un type qui a une valeur, la référence null (et est représenté par le littéral null):

Il existe également un type nul spécial , le type de l'expression null, qui n'a pas de nom. Étant donné que le type nul n'a pas de nom, il est impossible de déclarer une variable de type nul ou de convertir en type nul. La référence null est la seule valeur possible d'une expression de type nul. La référence null peut toujours être convertie en n'importe quel type de référence. En pratique, le programmeur peut ignorer le type nul et simplement prétendre qu'il nulls'agit simplement d'un littéral spécial pouvant être de n'importe quel type de référence.

Vous voudrez peut-être lire sur le modèle d'objet nul (que je ne recommande pas). Voir le wiki C2 ou Wikipedia pour en savoir plus sur ce modèle.



4

Non, n'est pas un objet car null instanceof Object retournera toujours false aussi il n'y a qu'un seul null, pas un pour chaque classe.


3
En fait, null instanceof <anytype>reviendra falseaussi.
Bombe

4

Selon la spécification Java ,

Il existe également un littéral nul spécial qui peut être utilisé comme valeur pour tout type de référence. null peut être assigné à n'importe quelle variable, à l'exception des variables de types primitifs. Vous ne pouvez pas faire grand-chose avec une valeur nulle au-delà de tester sa présence. Par conséquent, null est souvent utilisé dans les programmes comme marqueur pour indiquer qu'un objet n'est pas disponible.


4

Java gère les objets via des références. Null est une ventilation de OO-ness de Java, car il vous laisse sous le niveau OO. Non ce n'est pas un objet, c'est une VALEUR d'une référence. Et cela n'a rien à voir avec les paradigmes d'objets, mais concerne la plomberie de Java, qui active les objets.


3

Null est-il une instance de java.lang.Object? Non.

Null est-il un objet ? dépend de la définition de « est ».


2
Object foo = null;
System.out.println(foo.toString()); 

La première ligne montre nullpeut être assignée au type Object, mais la deuxième ligne démontrera que ce n'est certainement pas un Objectet aboutit finalement à unjava.lang.NullPointerException


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.