Pourquoi coulé après un instanceOf?
Dans l'exemple ci-dessous (à partir de mon coursepack), nous voulons donner à la Square
instance c1
la référence d'un autre objet p1
, mais uniquement si les 2 sont de types compatibles.
if (p1 instanceof Square) {c1 = (Square) p1;}
Ce que je ne comprends pas ici, c'est que nous avons d'abord vérifier que p1
est en effet un Square
, et puis nous avons encore de voter pour elle. Si c'est un Square
, pourquoi cast?
Je soupçonne que la réponse se trouve dans la distinction entre l'apparent et les types réels, mais je suis confus néanmoins...
Edit:
Comment le compilateur de traiter:
if (p1 instanceof Square) {c1 = p1;}
Edit2:
C'est la question que instanceof
vérifie l' réelle type plutôt que de la apparente type? Et alors que le casting change la apparente type?
Merci,
JDelage
- C'est pourquoi il demande une question delnan...
- S'agissant de la question dans votre montage, pourquoi ne pas simplement essayer de le compiler vous-même? Vous n'avez pas besoin DONC de la communauté à agir comme un compilateur pour vous.
- Peters - point est bien pris, mon intérêt n'est pas vraiment ce qui allait se passer, mais plus de différences dans la façon dont le compilateur aurait parse que.
Vous devez vous connecter pour publier un commentaire.
Gardez à l'esprit, vous pouvez toujours affecter une instance de la Place pour un type plus haut dans la chaîne d'héritage. Vous pouvez ensuite lancer le moins le type spécifique de les plus spécifique, dans ce cas, vous devez être sûr que votre plâtre est valide:
Le compilateur ne pas en déduire que, puisque vous êtes dans le bloc, vous avez fait un succès de vérifier le type de l'objet. Un cast explicite est toujours nécessaire de dire au compilateur que vous le souhaitez pour référence l'objet que d'un type différent.
En C# vous pouvez effectuer l'enregistrement et la distribution à 1 appel:
Ce sera jeté
p1
à un Carré, et si la conversion échoue, c1 sera mis ànull
.Square
.if (p1 is Square s) { /* s is a non-null instance of Square, within this scope */ }
Il y a une différence entre la mesure si un objet tient dans une boîte, et fait mettre dans la boîte.
instanceof
est l'ancien, et le casting est le dernier.Parce que cet sucre syntaxique n'est pas encore ajoutés à la langue. Je pense qu'il a été proposé pour Java 7, mais il ne semble pas avoir saisi projet de pièce de monnaie
instanceof
est un très valables cas d'utilisation parfois, même s'il est souvent utilisé à mauvais escient.De l'ancien code ne fonctionnent pas correctement
La impield cast fonction est justifiée après tout, mais nous avons des difficultés pour mettre en œuvre cette FR de java, car des raisons de compatibilité descendante.
Voir ceci:
L'actuel JDK de dresser l'utilisation de la deuxième méthode déclarée.
Si nous mettons en œuvre ce FR en java, il serait procédé à utiliser la première méthode!
E. g. Si vous avez la main sur p1 de type Objet, le compilateur ne sait pas qui il est, en fait, un exemple de Carré, de sorte que des Méthodes, etc. ne serait pas accessible. Le vérifie simplement si pour un certain type de retour, vrai/faux, mais cela ne change pas le type de la variable p1.
La variable p1 a quel que soit le type il a commencé avec, disons - Forme. p1 est une Forme, et seulement une Forme, peu importe que son contenu actuel arriver à être un Carré. Vous pouvez appeler, disons - côté() sur un Carré, mais pas sur une Forme. Tant que vous êtes identification de l'entité en question via la variable p1, dont le type est de la Forme, vous ne pouvez pas appeler côté() sur celui-ci, en raison du type de la variable. La façon dont Java du type de système fonctionne, si on peut appeler p1.côté() quand tu sais que c'est un Carré, vous pouvez toujours appel p1.côté(). Mais p1 peut contenir non seulement des Formes Carrées, mais aussi (dire) le Cercle de Formes, et il serait une erreur d'appeler p1.côté() lorsque p1 lieu d'un Cercle. Si vous avez besoin d'une autre variable pour représenter la Forme qui vous arrive de savoir est un Carré, une variable dont le type est Carré. C'est pourquoi le casting est nécessaire.
Si
c1
est déclaré comme un type deSquare
puis le casting est nécessaire. Si elle est déclarée comme uneObject
ensuite casting n'est pas nécessaire.Le test est fait pour éviter de
ClassCastExceptions
au moment de l'exécution:Si vous êtes absolument positif que
p1
est unSquare
, alors vous n'avez pas à tester. Mais laissons cela à des méthodes privées...De ne pas être désagréable, mais vous avez à dire au compilateur ce que vous voulez faire parce que l'alternative serait pour elle de deviner ce que vous essayez de faire. Bien sûr, vous pourriez penser, "Si je suis de vérifier le type d'un objet, ÉVIDEMMENT, cela doit signifier que je veux le lancer de ce type." Mais qui le dit? C'est peut-être ce que vous faites et peut-être qu'il ne l'est pas.
Sûr, dans un cas simple comme
Mon intention est assez évident. Ou est-il? Peut-être ce que je veux vraiment est:
Ou si j'ai écrit:
Qu'attendez-vous le compilateur faire? Ce type devrait-il assumer pour x?
RE les commentaires que instanceof est obsolète ou sinon une mauvaise idée: Il peut certainement être mal utilisée. J'ai récemment travaillé sur un programme où l'auteur original créé six classes qui se sont tous révélés être des pages et des pages de long, mais identiques les uns aux autres, et la seule raison apparente pour avoir été, de sorte qu'il pouvait dire "x instanceof classA" par rapport à "x instanceof classB", etc. C'est, il a utilisé la classe comme un type de drapeau. Il aurait été mieux d'avoir une classe et ajouter un enum pour les différents types. Mais il y a aussi beaucoup de très bons usages. Peut-être le plus évident est quelque chose comme:
Comment voudriez-vous faire cela sans utiliser instanceof? Vous pourriez faire le paramètre de type Maclasse à la place de l'Objet. Mais alors il n'y a aucun moyen de l'appellent même avec un Objet générique, qui pourrait être très utile dans de nombreux cas. En effet, peut-être que je veux une collection de comprendre, de les dire, les Chaînes et les nombres Entiers, et je veux les comparaisons de la différence types de simplement retourner false.