Pourquoi ne pas Java ont initialiseur de listes comme en C++?
En C++, vous pouvez utiliser une liste d'initialiseur pour initialiser les champs de la classe avant que le constructeur ne commence à courir. Par exemple:
Foo::Foo(string s, double d, int n) : name(s), weight(d), age(n) {
//Empty; already handled!
}
Je suis curieux de savoir pourquoi Java ne dispose pas d'une fonctionnalité similaire. Selon de Base Java: Volume 1:
C++ utilise cette syntaxe spéciale pour appeler le champ des constructeurs. En Java, il n'est pas nécessaire, parce que les objets ont pas de sous-objets, seulement des pointeurs vers d'autres objets.
Voici mes questions:
-
Que veulent-ils dire par "parce que les objets ont pas de sous-objets?" Je ne comprends pas ce qu'est un sous-objet est (j'ai essayé de regarder vers le haut); signifient-ils une instanciation d'une sous-classe qui étend la classe mère?
-
Comme pour pourquoi Java n'a pas d'initialiseur de listes comme C++, je suppose que la raison en est que tous les champs sont déjà initialisés par défaut en Java, et aussi parce que Java utilise le
super
mot-clé pour appeler le super(ou la base en C++ lingo) le constructeur de la classe. Est-ce correct?
Vous devez vous connecter pour publier un commentaire.
En C++, initialiseur de listes sont nécessaires en raison de quelques fonctionnalités de langage qui soit ne sont pas présents dans l'utilisation de Java ou de travailler différemment en Java:
const
: En C++, vous pouvez définir les champs qui sont marquésconst
qui ne peut pas être affecté et doit être initialisé dans la liste d'initialiseur. Java n'ontfinal
champs, mais vous pouvez affecter àfinal
champs dans le corps d'un constructeur. En C++, de l'affectation à unconst
champ dans le constructeur est illégal.Références: En C++, les références (par opposition à des pointeurs) doit être initialisé à se lier à un objet. Il est illégal de créer une référence sans un initialiseur. En C++, le chemin que vous indiquez, c'est avec l'initialiseur de liste, car si vous étiez à se référer à la référence dans le corps du constructeur sans d'abord l'initialiser, vous seriez à l'aide d'un non initialisé de référence. En Java, les références aux objets se comportent comme C++ les pointeurs et peut être attribué à après créées. Ils ont juste valeur par défaut pour
null
autrement.Directe de sous-objets. En C++, un objet peut contenir des objets directement en tant que champs, alors qu'en Java, les objets ne peuvent tenir références à ces objets. C'est, en C++, si vous déclarez un objet qui a une
string
en tant que membre, l'espace de stockage pour que la chaîne est directement intégré à l'espace de l'objet lui-même, alors qu'en Java que vous venez de trouver de la place pour un renvoi à d'autresString
objet stocké ailleurs. Par conséquent, C++ doit fournir un moyen pour vous de donner à ces sous-objets de valeurs d'origine, car sinon on venait de séjour non initialisée. Par défaut, il utilise le constructeur par défaut pour ces types, mais si vous souhaitez utiliser un autre constructeur ou pas de constructeur par défaut est disponible la liste d'initialiseur vous donne un moyen de contourner cela. En Java, vous n'avez pas besoin de vous inquiéter à ce sujet parce que les références par défautnull
, et vous pouvez ensuite attribuer à eux pour désigner les objets que vous voulez vraiment se référer. Si vous souhaitez utiliser un non-constructeur par défaut, alors vous n'avez pas besoin d'aucune syntaxe spéciale pour elle; il suffit de régler la référence à un objet initialisé par le constructeur.Dans les rares cas où Java pourrait vouloir initialiseur de listes (par exemple, à l'appel de la superclasse des constructeurs ou de donner des valeurs par défaut pour ses champs), c'est géré par le biais de deux autres fonctions du langage: la
super
mot-clé à invoquer la superclasse des constructeurs, et le fait que les objets Java peuvent donner à leurs champs de valeurs par défaut au moment où elles sont déclarées. Depuis C++ a l'héritage multiple, avoir juste un seulsuper
mot-clé ne serait pas sans ambiguïté se référer à une seule classe de base, et avant C++11 C++ n'a pas de support par défaut initialiseurs dans une classe et ont dû compter sur l'initialiseur de listes.Espérons que cette aide!
C++
Il y a une différence entre
et
Ce dernier n'a pas besoin d'être initialisé (NULL). Le premier n'. Pensez-y comme un entier. Vous ne pouvez pas avoir un int sans valeur, MAIS vous pouvez avoir un int pointeur sans valeur.
Ainsi, lorsque vous avez:
Puis la déclaration:
crée automatiquement une instance de
OtherClass
dansvalue
. Par conséquent, siOtherClass
a l'initialisation, il doit être fait dans leClassType
constructeur. Cependant,reference
est juste un pointeur (l'adresse en mémoire) et peut rester non initialisée. Si vous voulez un exemple deOtherClass
vous devez utiliserJava
Il y a seulement
C'est l'équivalent d'un pointeur en C++. Dans ce cas, lorsque vous faites:
Vous n'avez pas automatiquement créer une instance de
OtherClass
. Par conséquent, vous n'avez pas à initialiser quoi que ce soit dans le constructeur, à moins que vous le souhaitez. Lorsque vous souhaitez qu'un objet deOtherClass
vous pouvez utiliserParce que Java n'a pas besoin d'eux afin de permettre l'initialisation des champs dont le type n'a pas de valeur nulle.
En C++
sans un initialiseur de membre pour
d
,D::D()
sera appelé, ce qui rend impossible d'initialiser le champ si il n'y a pas de zéro-type pourD
. Cela peut se produire lorsqueD::D()
est explicitement déclaréprivate
.En Java, il est connu la valeur zéro pour tous les types référence,
null
, de sorte qu'un champ peut toujours être initialisé.Java a également fait un gros travail pour veiller à ce que* tous
final
champs sont initialisés avant la première utilisation et avant que le constructeur se termine, alors que Java a une exigence comme C++const
champ d'initialisation de l'obligation, c'est juste surchargesthis.fieldName = <expression>
dans le corps du constructeur de champ moyen de l'initialisation.nil
que la valeur zéro pour les types de pointeur.bzero
ing un des objets jeux de mémoire, tous domaines de lazero-value
comme en Aller, ont tendance à préférer ce terme, alors que le langage Java spec utilise "valeur par défaut" depuis Java n'est pas spécifier un module nommé "dangereux" qui nécessite de spécifier quelque chose au sujet de l'objet de mise en page. Peut-être "valeur par défaut" ou "valeur initiale" serait mieux, surtout depuis le "zéro valeur" w.r.t. La norme IEEE 754 valeurs d'invites à la question "Qui de zéro?"