C a des pointeurs et Java a ce qu’on appelle des références. Ils ont certaines choses en commun dans le sens où ils indiquent tous quelque chose. Je sais que les pointeurs en C stockent les adresses qu’ils pointent. Est-ce que la référence stocke aussi l'adresse? En quoi sont-ils différents, si ce n'est que le pointeur est plus flexible et sujet aux erreurs?
97
final
référence en Java est presque équivalente à une référence en C ++. La raison pour laquelle ils ne sont pas exactement équivalents est qu’une référence C ++ n’est pas non plus nullable, alors qu’unefinal
référence en Java est nulle.Réponses:
Les références peuvent être implémentées en stockant l'adresse. Habituellement, les références Java sont implémentées en tant que pointeurs, mais cela n'est pas requis par la spécification. Ils peuvent utiliser une couche supplémentaire d'indirection pour permettre un ramassage des ordures plus facile. Mais au final, cela se résumera (presque toujours) à des pointeurs (de style C) impliqués dans la mise en œuvre de références (de style Java).
Vous ne pouvez pas faire de l'arithmétique de pointeur avec des références. La différence la plus importante entre un pointeur en C et une référence en Java est qu’il est impossible d’obtenir (et de manipuler) la valeur sous-jacente d’une référence en Java. En d'autres termes: vous ne pouvez pas faire de l'arithmétique de pointeur.
En C, vous pouvez ajouter quelque chose à un pointeur (c'est-à-dire l'adresse) ou soustraire quelque chose pour pointer sur des choses "proches" ou sur des endroits situés à n'importe quel endroit.
En Java, une référence pointe vers une chose et cette chose seulement. Vous pouvez faire en sorte qu'une variable contienne une référence différente , mais vous ne pouvez pas lui demander simplement de désigner "la chose après la chose d'origine".
Les références sont fortement typées. Une autre différence est que le type d'une référence est beaucoup plus strictement contrôlé en Java que le type d'un pointeur est en C. En C, vous pouvez avoir un
int*
et le convertir en unchar*
et simplement réinterpréter la mémoire à cet emplacement. Cette réinterprétation ne fonctionne pas en Java: vous pouvez uniquement interpréter l’objet à l’autre extrémité de la référence comme quelque chose qu’il est déjà (c’est-à-dire que vous pouvez transformer uneObject
référence enString
référence uniquement si l’objet pointé est réellement unString
).Ces différences rendent les pointeurs C plus puissants, mais aussi plus dangereux. Ces deux possibilités (arithmétique de pointeur et réinterprétation des valeurs pointées) ajoutent de la flexibilité à C et sont à l'origine d'une partie de la puissance du langage. Mais ils constituent également une source importante de problèmes, car s'ils ne sont pas utilisés correctement, ils peuvent facilement briser les hypothèses selon lesquelles votre code est construit. Et c'est assez facile de les utiliser incorrectement.
la source
memcpy
déplaçant un dans unchar[]
) et inversement. Si un pointeur est converti en une séquence de nombres qui est stockée quelque part (peut-être affiché à l'écran et copié par l'opérateur sur un bout de papier), toutes les copies du pointeur de l'ordinateur sont détruites et cette séquence de nombres est convertie. Pour revenir à un pointeur (peut-être après avoir été saisi par l'opérateur), le pointeur doit toujours indiquer la même chose que précédemment. Un programme qui ...Les références C ++ sont encore différentes.
Ils doivent être initialisés et ne peuvent pas être nuls (du moins pas dans un programme bien formé) et ne peuvent pas être replacés pour faire référence à autre chose. une référence C ++ ressemble beaucoup plus à un alias d'objet.
Une autre différence importante entre les pointeurs et les références Java / C ++ est que vous pouvez utiliser l'adresse d'un pointeur auquel vous ne pouvez pas accéder (par exemple, une référence C ++ ne doit pas exister sous la forme d'un objet en mémoire). pointeur vers un pointeur mais pas une référence à une référence
la source
Les références Java et les pointeurs C diffèrent par exactement deux points:
char
,int
etc.).Quelqu'un a écrit que les références sont fortement typées, car vous ne pouvez pas forcer le compilateur à traiter un
int*
commechar*
.Complètement à part le fait que cette conversion particulière est réellement sûre , il n'y a pas de polymorphisme en C, de sorte que la comparaison est un non-démarreur.
Certes, Java est plus typé que C, bien que ce ne soit pas une caractéristique des pointeurs C ni des références Java, vous devez utiliser le JNI pour casser la sécurité de type (mis à part le non respect des restrictions génériques), mais même en C, vous devez forcer. le compilateur.
Quelqu'un a écrit que les références Java peuvent être mises en œuvre en tant que pointeurs C, auquel je dis que, comme ils sont strictement moins puissants, sur les machines 32Bit ils sont généralement, si la machine virtuelle Java est implémenté en C . Bien que sur les machines 64 bits, ce sont normalement des pointeurs d’objets ordinaires ("POO compressés") compressés pour économiser de l’espace et de la bande passante.
Quoi qu'il en soit, ces pointeurs C ne doivent pas non plus être équivalents aux adresses matérielles, même s'ils sont généralement (> 99% des implémentations) pour des raisons de performances.
Enfin, il s’agit d’un détail d’implémentation qui n’est pas exposé au programmeur.
la source
Ils sont légèrement différents. En Java, une copie de la référence est copiée dans la pile d'une fonction appelée, pointant sur le même objet que la fonction appelante et vous permettant de manipuler cet objet. Cependant, vous ne pouvez pas modifier l'objet auquel la fonction appelante fait référence.
Considérons le code Java suivant
Considérons maintenant un pointeur en c ++:
la source