Qu'est-ce que c'est null
?
Est-ce null
une instance de quelque chose?
À quel ensemble null
appartient-il?
Comment est-il représenté dans la mémoire?
Qu'est-ce que c'est null
?
Est-ce null
une instance de quelque chose?
À quel ensemble null
appartient-il?
Comment est-il représenté dans la mémoire?
Réponses:
Null est-il une instance de quoi que ce soit?
Non, il n'y a pas de type qui null
soit un instanceof
.
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
Au moment de l'exécution, le résultat de l'
instanceof
opérateur esttrue
si la valeur de RelationalExpression ne l'est pasnull
et que la référence peut être convertie en ReferenceType sans augmenter aClassCastException
. Sinon, le résultat estfalse
.
Cela signifie que pour tout type E
et R
, pour tout E o
, où o == null
, o instanceof R
est toujours false
.
À quel ensemble appartient «null»?
Il existe également un type null 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 du type nul ou de transtyper en type nul . Lanull
référence est la seule valeur possible d'une expression de type null . Lanull
référence 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 qu'ilnull
s'agit simplement d'un littéral spécial qui peut être de n'importe quel type de référence.
Qu'est-ce qui est nul?
Comme le dit la citation de JLS ci-dessus, dans la pratique, vous pouvez simplement prétendre que c'est "simplement un littéral spécial qui peut être de n'importe quel type de référence".
En Java, null == null
(ce n'est pas toujours le cas dans d'autres langues). Notez également que par contrat, il possède également cette propriété spéciale (de java.lang.Object
):
public boolean equals(Object obj)
Pour toute
null
valeur non référencex
,x.equals(null)
devraitreturn false
.
Il s'agit également de la valeur par défaut (pour les variables qui en disposent) pour tous les types de référence:
- Chaque variable de classe, variable d'instance ou composant de tableau est initialisé avec une valeur par défaut lors de sa création:
- Pour tous les types de référence, la valeur par défaut est
null
.
La façon dont cela est utilisé varie. Vous pouvez l'utiliser pour activer ce qu'on appelle l' initialisation différée des champs, où un champ aurait sa valeur initiale null
jusqu'à ce qu'il soit réellement utilisé, où il est remplacé par la valeur "réelle" (qui peut être coûteuse à calculer).
Il existe également d'autres utilisations. Prenons un exemple réel de java.lang.System
:
public static Console console()
Renvoie : la console système, le cas échéant, sinon
null
.
Il s'agit d'un modèle d'utilisation très courant: null
est utilisé pour indiquer la non-existence d'un objet.
Voici un autre exemple d'utilisation, cette fois de java.io.BufferedReader
:
public String readLine() throws IOException
Renvoie : A
String
contenant le contenu de la ligne, sans inclure les caractères de terminaison de ligne, ounull
si la fin du flux a été atteinte.
Donc ici, readLine()
reviendrait instanceof String
pour chaque ligne, jusqu'à ce qu'elle retourne finalement un null
pour signifier la fin. Cela vous permet de traiter chaque ligne comme suit:
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
On peut concevoir l'API pour que la condition de terminaison ne dépende pas du readLine()
retour null
, mais on peut voir que cette conception a l'avantage de rendre les choses concises. Notez qu'il n'y a pas de problème avec les lignes vides, car une ligne vide "" != null
.
Prenons un autre exemple, cette fois de java.util.Map<K,V>
:
V get(Object key)
Renvoie la valeur à laquelle la clé spécifiée est mappée, ou
null
si cette mappe ne contient aucun mappage pour la clé.Si cette mappe autorise des
null
valeurs, une valeur de retour denull
n'indique pas nécessairement que la mappe ne contient pas de mappage pour la clé; il est également possible que la carte mappe explicitement la clénull
. L'containsKey
opération peut être utilisée pour distinguer ces deux cas.
Ici, nous commençons à voir comment l'utilisation null
peut compliquer les choses. La première instruction indique que si la clé n'est pas mappée, elle null
est renvoyée. La deuxième déclaration indique que même si la clé est mappée, elle null
peut également être renvoyée.
En revanche, java.util.Hashtable
simplifie les choses en n'autorisant pas les null
clés et les valeurs; son V get(Object key)
, s'il revient null
, signifie sans ambiguïté que la clé n'est pas mappée.
Vous pouvez lire le reste des API et trouver où et comment null
est utilisé. Gardez à l'esprit qu'ils ne sont pas toujours des exemples de bonnes pratiques .
D'une manière générale, null
sont utilisés comme valeur spéciale pour signifier:
Comment est-il représenté dans la mémoire?
En Java? Aucun de vos soucis. Et c'est mieux gardé de cette façon.
null
une bonne chose?C'est maintenant subjectivement limite. Certaines personnes disent que cela null
provoque de nombreuses erreurs de programmation qui auraient pu être évitées. Certains disent que dans un langage qui attrape NullPointerException
comme Java, il est bon de l'utiliser car vous échouerez rapidement sur les erreurs de programmation. Certaines personnes évitent null
d'utiliser le modèle d'objet nul , etc.
Il s'agit d'un énorme sujet en soi, il est donc préférable de le discuter comme réponse à une autre question.
Je terminerai ceci par une citation de l'inventeur de null
lui-même, CAR Hoare (de renommée quicksort):
J'appelle cela mon erreur d'un milliard de dollars. C'était l'invention de la
null
référence en 1965. A cette époque, je concevais le premier système de type complet pour les références dans un langage orienté objet (ALGOL W). Mon objectif était de garantir que toute utilisation des références soit absolument sûre, la vérification étant effectuée automatiquement par le compilateur. Mais je n'ai pas pu résister à la tentation de mettre unenull
référence, tout simplement parce qu'elle était si simple à mettre en œuvre. Cela a conduit à d'innombrables erreurs, vulnérabilités et plantages du système, qui ont probablement causé un milliard de dollars de douleur et de dommages au cours des quarante dernières années.
La vidéo de cette présentation va plus loin; c'est une montre recommandée.
NIL
) en 1960, et probablement plus tôt. Mais je ne pense pas que Hoare essaie vraiment de revendiquer l'invention de références nulles dans cette citation.
Null est-il une instance de quoi que ce soit?
C'est pourquoi null instanceof X
reviendra false
pour toutes les classes X
. (Ne vous laissez pas berner par le fait que vous pouvez affecter null
à une variable dont le type est un type d'objet. À proprement parler, l'affectation implique une conversion de type implicite; voir ci-dessous.)
À quel ensemble appartient «null»?
Il s'agit du seul et unique membre du type null, où le type null est défini comme suit:
"Il existe également un type null spécial, le type de l'expression null, qui n'a pas de nom. Comme le type null n'a pas de nom, il est impossible de déclarer une variable de type null ou de transtyper en type null. Le null référence est la seule valeur possible d'une expression de type null. 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 null et prétendre simplement que null est simplement un littéral spécial qui peut être de n'importe quel type. Type de référence." JLS 4.1
Qu'est-ce qui est nul?
Voir au dessus. Dans certains contextes, null
est utilisé pour désigner "aucun objet" ou "inconnu" ou "indisponible", mais ces significations sont spécifiques à l'application.
Comment est-il représenté dans la mémoire?
C'est spécifique à l'implémentation, et vous ne pourrez pas voir la représentation de null
dans un programme Java pur. (Mais null
est représenté comme une adresse / pointeur de machine zéro dans la plupart, sinon toutes les implémentations Java.)
Qu'est-ce qui est nul?
Ce n'est rien.
Null est-il une instance de quoi que ce soit?
Non car ce n'est rien. Cela ne peut pas être l'instance de quelque chose.
À quel ensemble appartient null?
Aucun ensemble
Comment est-il représenté dans la mémoire?
Si certaines références le désignent comme:
Object o=new Object();
Dans la mémoire de tas, un espace est attribué au nouvel objet créé. Et o pointera vers cet espace attribué en mémoire.
Maintenant o=null;
Cela signifie maintenant que o ne pointera pas vers cet espace mémoire de l'objet.
Le mot clé null est un littéral qui représente une référence nulle, une référence qui ne fait référence à aucun objet . null est la valeur par défaut des variables de type référence.
Peut-être aussi jeter un oeil à
Null en Java (tm)
En C et C ++, "NULL" est une constante définie dans un fichier d'en-tête, avec une valeur comme:
0
ou:
0L
ou:
((void*)0)
selon les options du compilateur et du modèle de mémoire. NULL ne fait pas à proprement parler partie de C / C ++ lui-même.
En Java (tm), "null" n'est pas un mot-clé, mais un littéral spécial de type null. Il peut être converti en n'importe quel type de référence, mais pas en n'importe quel type primitif tel que int ou booléen. Le littéral nul n'a pas nécessairement la valeur zéro. Et il est impossible de transtyper en type null ou de déclarer une variable de ce type.
Représentation du bytecode
Java null
a un support JVM direct: trois instructions sont utilisées pour l'implémenter:
aconst_null
: par exemple, pour définir une variable null
comme dansObject o = null;
ifnull
et ifnonnull
: par exemple pour comparer un objet null
comme dansif (o == null)
Le chapitre 6 "Le jeu d'instructions de la machine virtuelle Java" mentionne ensuite les effets de null
sur d'autres instructions: il en lance un NullPointerException
pour beaucoup d'entre elles.
2.4. "Types et valeurs de référence" mentionne également null
en termes génériques:
Une valeur de référence peut également être la référence null spéciale, une référence à aucun objet, qui sera désignée ici par null. La référence null n'a initialement aucun type d'exécution, mais peut être convertie en n'importe quel type. La valeur par défaut d'un type de référence est null.
null
est une valeur spéciale, ce n'est pas une instance de quoi que ce soit. Pour une raison évidente, cela ne peut être instanceof
rien.
null
est une valeur spéciale qui n'est une instance d'aucune classe. Ceci est illustré par le programme suivant:
public class X {
void f(Object o)
{
System.out.println(o instanceof String); // Output is "false"
}
public static void main(String[] args) {
new X().f(null);
}
}
null
n'est pas une instance de String
.
void f(String o)
, cela aurait plus de sens.
null en Java est similaire à nullptr en C ++.
Programme en C ++:
class Point
{
private:
int x;
int y;
public:
Point(int ix, int iy)
{
x = ix;
y = iy;
}
void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
Point* p = new Point(3,5);
if (p != nullptr)
{
p->print();
p = nullptr;
}
else
{
std::cout << "p is null" << std::endl;
}
return 0;
}
Même programme en Java:
public class Point {
private int x;
private int y;
public Point(int ix, int iy) {
x = ix;
y = iy;
}
public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
public static void main(String[] args) {
Point p = new Point(3,5);
if (p != null)
{
p.print();
p = null;
}
else
{
System.out.println("p is null");
}
}
}
Comprenez-vous maintenant des codes ci-dessus ce qui est nul en Java? Si non, je vous recommande d'apprendre les pointeurs en C / C ++ et vous comprendrez.
Notez qu'en C, contrairement à C ++, nullptr n'est pas défini, mais NULL est utilisé à la place, ce qui peut également être utilisé en C ++, mais en C ++ nullptr est plus préférable que NULL, car le NULL en C est toujours lié aux pointeurs et c'est il, donc en C ++ le suffixe "ptr" a été ajouté à la fin du mot, et aussi toutes les lettres sont maintenant en minuscules, mais c'est moins important.
En Java, chaque variable de classe de type non primitive est toujours une référence à un objet de ce type ou héritée et null est une référence d'objet de classe null, mais pas un pointeur null, car en Java, il n'y a pas de "pointeur", mais des références à la classe les objets sont utilisés à la place, et null en Java est lié aux références aux objets de classe, vous pouvez donc aussi l'appeler "nullref" ou "nullrefobj", mais c'est long, alors appelez-le simplement "null".
En C ++, vous pouvez utiliser des pointeurs et la valeur nullptr pour les membres / variables facultatifs , c'est-à-dire le membre / variable qui n'a pas de valeur et s'il n'a pas de valeur, il est égal à nullptr, alors comment null en Java peut être utilisé par exemple.
Il existe deux grandes catégories de types en Java: primitive et référence . Variables déclarées d'un magasin de type primitif; les variables déclarées d'un type de référence stockent les références.
String x = null;
Dans ce cas, l'instruction d'initialisation déclare une variable «x». «X» stocke la référence de chaîne. C'est nul ici. Tout d'abord, null n'est pas une instance d'objet valide, il n'y a donc pas de mémoire allouée pour cela. Il s'agit simplement d'une valeur qui indique que la référence d'objet ne fait pas actuellement référence à un objet.
Une façon intéressante de voir null en java à mon avis est de le voir comme quelque chose qui NE dénote PAS une absence d'information mais simplement comme une valeur littérale qui peut être assignée à une référence de n'importe quel type. Si vous y pensez si cela dénotait une absence d'information, alors pour a1 == a2 être vrai n'a pas de sens (au cas où on leur attribuerait une valeur nulle) car ils pourraient vraiment pointer vers N'IMPORTE QUEL objet (nous avons simplement Je ne sais pas sur quels objets ils devraient pointer) ... Au fait, null == null renvoie true en java. Si java, par exemple, serait comme SQL: 1999, alors null == null retournerait inconnu (une valeur booléenne dans SQL: 1999 peut prendre trois valeurs: true, false et unknown mais en pratique unknown est implémenté comme null dans les systèmes réels) ... http://en.wikipedia.org/wiki/SQL
Réponse courte et précise qui répond formellement à toutes vos questions de JLS:
3.10.7. The Null Literal
Le type null a une valeur, la référence null, représentée par le null littéral null, qui est formé de caractères ASCII.
Un littéral nul est toujours de type nul.
Seule une référence de type affectée à null est allouée. Vous n'affectez aucune valeur (objet) à la référence. Cette allocation est spécifique à la machine virtuelle Java combien de référence prendra et dans quelle zone mémoire elle sera allouée.