La coulée de variables en Java
Je me demande si quelqu'un pourrait me dire comment casting fonctionne? Je comprends quand je devrais le faire, mais pas vraiment comment il fonctionne. Sur les types de données primitifs je comprends en partie, mais quand il s'agit de mouler des objets que je ne comprends pas comment il fonctionne.
Comment un objet avec l'Objet de type juste soudainement être jeté à, disons, MyType
(juste un exemple) et ensuite obtenir toutes les méthodes?
- Suggestions de lecture: Héritage
- javaseeeedu.blogspot.com/2015/12/casting-part-1.html
Vous devez vous connecter pour publier un commentaire.
Casting en Java n'est pas magique, c'est vous dire au compilateur qu'un Objet de type A est en fait plus spécifiques de type B, et donc d'avoir accès à toutes les méthodes sur B que tu n'aurais pas eu autrement. Vous n'êtes pas effectuer n'importe quel type de magie ou de la conversion lors de l'exécution de la coulée, vous êtes essentiellement de dire au compilateur "faites-moi confiance, je sais ce que je fais et je peux vous garantir que cet Objet au cette ligne est en fait une <Insert type moulé ici>." Par exemple:
Ci-dessus est très bien, pas de la magie et tous bien. L'objet stocké dans o est en fait une chaîne de caractères, et donc on peut se convertir en une chaîne sans aucun problème.
Il y a deux façons de ce qui pourrait aller mal. Tout d'abord, si vous êtes à la conversion entre les deux types complètement différents de hiérarchies d'héritage alors le compilateur saura que vous êtes stupide et vous arrêter:
Deuxièmement, si ils sont dans la même hiérarchie, mais encore une défaillance de fonte puis un
ClassCastException
sera levée lors de l'exécution:Cela signifie essentiellement que vous avez violé le compilateur en confiance. Vous avez dit qu'il vous permet de garantir à l'objet est d'un type particulier, et il n'est pas.
Pourquoi avez-vous besoin de casting? Eh bien, pour commencer, vous n'aurez besoin que lorsqu'on passe d'un type plus général au plus spécifique de type. Par exemple,
Integer
hérite deNumber
, donc si vous voulez stocker unInteger
comme unNumber
alors que c'est ok (puisque tous les nombres Entiers sont des Nombres.) Toutefois, si vous voulez aller dans l'autre sens, vous avez besoin d'un cast pas tous les Nombres sont des Entiers (ainsi que le nombre Entier nous avonsDouble
,Float
,Byte
,Long
, etc.) Et même s'il y a une sous-classe dans votre projet ou le JDK, quelqu'un pourrait facilement créer un autre et de le distribuer, de sorte que vous n'avez aucune garantie, même si vous pensez que c'est un seul choix évident!Concernant l'utilisation de la coulée, vous voyez toujours le besoin dans certaines bibliothèques. Avant Java 5, il a été largement utilisé dans les collections et les divers autres classes, puisque toutes les collections travaillé sur l'ajout d'objets et puis le casting du résultat que vous avez de nouveau la collection. Cependant, avec l'arrivée des génériques beaucoup de les utiliser pour la coulée a disparu - il a été remplacé par un générique qui offrent un alternative plus sûre, sans le potentiel pour ClassCastExceptions (en fait, si vous utiliser des génériques proprement et il se compile sans avertissements, vous avez une garantie que vous n'aurez jamais une ClassCastException.)
Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()
. Dans les deux cas, vous ne devriez pas avoir besoin de demander à la classe d'une primitive de manière dynamique, car sigetLatitude()
renvoie un double primitif, vous savez toujours qu'il va faire de la promotion pour unDouble
objet.for (final Submodel submodel : submodels) { final NumericSubmodel numericSubmodel = (NumericSubmodel) submodel; ...}
la NumericSubmodel constructeur ne sera jamais appelé, à droite? et c'est des champs supplémentaires (non présent dans le sous-modèle) ne seront pas réglées.En fait, le casting ne fonctionne pas toujours. Si l'objet n'est pas un
instanceof
la classe que vous soyez un moulage, vous obtiendrez unClassCastException
au moment de l'exécution.Supposons que vous vouliez jeter un
String
à unFile
(oui ça n'a aucun sens), vous ne pouvez pas le jeter directement parce que lesFile
classe n'est pas un enfant et non d'un parent de laString
classe (et le compilateur se plaint).Mais vous pourriez lancer votre
String
àObject
, car unString
est unObject
(Object
est le parent). Ensuite, vous pouvez lancer l'objet d'unFile
, car un Fichier est unObject
.Pour vous tous les opérations sont "légales" de frappe point de vue au moment de la compilation, mais cela ne signifie pas qu'il fonctionne au moment de l'exécution !
Le compilateur va permettre à ce même s'il n'a pas de sens, mais il va se bloquer lors de l'exécution de cette exception:
Coulée de référence ne fonctionnera que si c'est un
instanceof
ce type. Vous ne pouvez pas jeter aléatoire références. Aussi, vous avez besoin de lire plus surMoulage d'Objets
.par exemple