Mais à quoi sert instanceof ? [Java] - Java - Programmation
Marsh Posté le 22-02-2003 à 18:16:47
à connaitre le type d'une variable
exemple
Code :
|
Marsh Posté le 22-02-2003 à 18:20:42
++Taz a écrit : à connaitre le type d'une variable
|
Oui d'accord, mais :
- si o est une instance d'une classe dérivée de Truc, (o instanceof Truc) est vrai.
- o.getClass() permet de faire la même chose.
Marsh Posté le 22-02-2003 à 19:50:50
R3g a écrit : |
En effet une bonne conception permet d'eviter l'utilisation cet operateur.
C'est pratique pour les rustines de dernières minutes
Marsh Posté le 22-02-2003 à 20:03:49
Deltanyne a écrit : |
en quoi c'est pas objet d'utiliser instanceof ?
Marsh Posté le 22-02-2003 à 20:06:35
instanceof c pratik kan par exemple tu fait redéfini la méthode equals de la class objet, paske la compilataur bosse avec la classe déclaré et il fau checké la class réeel
ps:vi je parle pas fr
Marsh Posté le 22-02-2003 à 20:14:45
R3g a écrit : |
non, par exemple :
Code :
|
Marsh Posté le 22-02-2003 à 20:15:20
noldor a écrit : en quoi c'est pas objet d'utiliser instanceof ? |
C'est pas que c'est pas objet en soit, maisca permet très facilement de passer outre l'aspect "transparent" du polymorphisme, et donc je trouve ca dangereux.
Epok > deja dit plus haut, je pense que dans ce cas il vaut mieux utiliser la classe Class.
Marsh Posté le 22-02-2003 à 20:19:54
benou a écrit :
|
Ben c'est justement ce que je lui reproche moi. On peut pas savoir pourquoi c'est vrai (c'est la classe qu'on veut ou c'est une classe derivée ?)
Je pense que c'est mieux de :
Code :
|
Marsh Posté le 22-02-2003 à 20:21:55
Mais bon je reconnais que dans le cas de equals(), c'est bien pratique. Mais est-ce que c'est plus sale de (c'est ce que je faisais jusqu'à maintenant) faire le cast dans un try et catcher la ClassCastException ?
Marsh Posté le 22-02-2003 à 20:23:04
isSsignableFrom revient exactement au même que instanceof ...
Marsh Posté le 22-02-2003 à 20:27:10
benou a écrit : isSsignableFrom revient exactement au même que instanceof ... |
Oui je reconnais. En fait je commence à revenir sur mes positions. Simplement j'ai été surpris de decouvrir cet operateur. C'est le genre de truc dont je pensais que ca pouvait exister en C++ mais pas en Java. Je continue à croire que ca permet de salement briser le concept objet.
Marsh Posté le 22-02-2003 à 20:30:54
ben c'est sur qu'on peut considérer que l'héritage casse l'encapsulation
sinon moi je trouve important et sain le comportement de instanceof, encore heureux qu'un vecteur qui implements List, puisse etre considérer comme une list
Marsh Posté le 22-02-2003 à 20:40:23
++Taz a écrit : ben c'est sur qu'on peut considérer que l'héritage casse l'encapsulation |
Oui bien sur, presenté comme ca... Bon ok j'admets que j'ai dit une connerie.
Marsh Posté le 22-02-2003 à 20:45:35
R3g a écrit : J'ai decouvert l'existence de cet opérateur il y a peu, mes profs s'étant bien gardé de m'en révéler l'existence (à juste titre je pense) pendant leurs cours de Java. |
C'est surtout utile pour les outils du langage, pas pour les applications, un explorateur par exemple pourrait en avoir besoin, pour des trucs un peu introspectifs etc.
En général, j'insulte les gens qui l'utilisent dans leur application, c'est souvent dû à un manque de connaissance, le top c'est le mec qui fait (enfin qui essaye) de faire un Switch sur un getClass ou qui branche sur instanceof.
Tu demandes pas son type à un objet que tu connais pas, tu lui demande de faire une action en tenant compte _ton_ type (quand tu écris une classe, donc que tu choisis un point de vue). Si la relation est réciproque (suivant les actions), tu dois te tenir prêt à répondre à toute demande du même style, éventuellement en renvoyant la politesse.
Marsh Posté le 22-02-2003 à 20:47:54
nraynaud a écrit : |
Ben voila, c'est comme ca que je voyais les choses. Maintenant, c'est vrai que surcharger equals(), compareTo() etc. sans caster l'objet, ca n'a pas de sens.
Marsh Posté le 22-02-2003 à 21:02:54
R3g a écrit : |
Si t'es dans un domaine métier, tu utilises les fonctions métier, pas les fonctions de la classe Object, tu auras un typage beaucoup plus fin -> sécurité, rapidité. Comparer un MonAppInteger avec UnMonAppBigInteger par equals() me parraît un peu fumeux sachant la tronche du contrat de equals().
D'autre part, quand-bien même equals() nécessiterait une bidouille pour fonctionner (je la sens mal depuis le début cette fonction, vivement les generics corrects), c'est très loin d'être la majorité des cas.
Marsh Posté le 22-02-2003 à 21:07:06
nraynaud a écrit : |
C'est sur, seulement quand tu surcharges equals dans MonAppInteger, tu sais pas par quel abruti ta classe va pouvoir utilisée, alors il vaut mieux prendre des précautions.
Marsh Posté le 22-02-2003 à 22:11:49
R3g a écrit : |
Le problème vient du fait que equals n'a rien à foutre dans object, mais sans equals, pas de collections. Donc re-vivement des generics, le pb, ça va être que maintenant, ils vont vouloir être compatibles au niveau source et ça va encore être un fossile qui va traîner dans le langage.
Je viens de regarder eiffel :
1) il possède la même méthode, typée plus finement (like Current)
2) le système de types ne permet pas vraiment de faire fondamentalement mieux que java (un peu mais pas beaucoup) en polymorphisme.
3) Il utilise la même merde que java au niveau des collections (l'égalité de Any), je suis déçu.
4) il propose une tentative d'affectation dans un cas simulaire dans son bouquin (p.622).
Marsh Posté le 23-02-2003 à 01:41:56
moi-même a écrit : |
De toute façon, même s'il a fait largement progresser l'informatique,je pense que je vais aller mettre une beigne moi-même à Meyer. Il a pas fait que ça comme conneries.
Marsh Posté le 24-02-2003 à 10:29:23
Quid de Ada ? (ce n'est pas un troll, mais une vraie question)
Ses concepteurs avaient pris des partis pris assez originaux sur certains points. Par exemple :
Les types dits privés ont un opérateur d'affectation et d'égalité implicites, alors que les types limités privés n'en ont pas (mais seul l'opérateur d'égalité peut être redéfini en tant qu'opérateur en Ada). Les arguments de ces opérateurs sont toujours strictement typés (exemple : "function operator=(left : Complex; right : Complex) returns boolean" ).
Par ailleurs, quand une classe "Mere" a une méthode à 2 arguments de type "Mere", sa sous-classe fille hérite d'une méthode à 2 arguments de type "Fille" (autrement dit, l'héritage ne porte pas que sur le type de l'objet receveur, mais potentiellement sur le type de tous les arguments).
Marsh Posté le 24-02-2003 à 14:57:39
J'aurais trouvé une utilisation de instanceOf.
Le contexte (mais c'est un détail), c'est celui de la création d'un value object (VO) en utilisant la stratégie value object factory (oui, je sais, ça fait pompeux comme ça...)
Le principe consiste à utiliser la reflection pour copier les champs de ClassA dans ClassAVO. Un peu de code...
Code :
|
Par contre, je ne veux pas recopier la valeur dependent, mais créer un VO à partir de dépendent.
Donc avant de copier le champ, je vérifie si il est instanceOf de VOMaker pour savoir si je peux créer un VO.
Vous en pensez quoi ?
------------------
Pour ceux que ça interesse, je me base sur le code généré par Together pour ce pattern
Code :
|
edit : correction des tabulations foireuses + balise cpp
Marsh Posté le 24-02-2003 à 14:59:24
Remplace tes balises "code" par des balises "cpp", on lira meixu ton code...
Marsh Posté le 24-02-2003 à 17:58:58
moi je m'en sers justement à cause du polymorphisme...
si tu as des objets totalement hétérogène dans une liste, tu dois les tester avec instanceof
Code :
|
tu vas me dire qu'on pourrait utiliser la même méthode pour les deux objets, et je te réponds que quand les classes existent, tu t'amuse pas à en dériver juste pour une méthode...
mais je suis pas un hardcore coder
Marsh Posté le 24-02-2003 à 18:14:05
Predicator a écrit : moi je m'en sers justement à cause du polymorphisme...
|
Ben à ta place je serais tenté de redéfinir truc.toString pour qu'elle retourne getVariableTruc.
Bon bien sûr si truc est une interface, il faudrait utiliser une class abstraite entre ton interface et tes implémentations, mais parfois on a la flemme
Marsh Posté le 24-02-2003 à 18:25:21
_gtm_ a écrit : |
c'est bien ce que je dis...
Truc et Bidule sont des classes existantes de Java...
par exemple, Truc = JTextField et Bidule = JComboBox...
tu as donc
Code :
|
et
Code :
|
tu vas pas t'amuser à dériver toutes les classes que tu utilises si ?
Marsh Posté le 24-02-2003 à 18:55:12
J'ai pas tout lu, je connais pas JAVA et encore moins InstanceOf, mais :
Citation : public class Truc |
Pourquoi accepter le type Object si c'est pour juste apres l'ignorer ?
C'est pas plus simple de remplacer par
boolean equals(Truc o) ?
Marsh Posté le 24-02-2003 à 19:00:53
HelloWorld a écrit : J'ai pas tout lu, je connais pas JAVA et encore moins InstanceOf, mais :
|
si il fait comme tu dis, ça surcharge plus la méthode equals de Object
Marsh Posté le 24-02-2003 à 19:05:00
HelloWorld a écrit : J'ai pas tout lu, je connais pas JAVA et encore moins InstanceOf, mais :
|
C'est parce que tu connais pas Java. En java, toutes les classes dérivent implicitement de la classe Object. Et Object possède une méthode equals(Object). Donc equals peut etre appelée sur n'importe quel objet. Il est donc souvent nécessaire de la surcharger pour les classes que tu crée, et il faut que ta méthode aie la meme signature.
Le vrai problème est, comme ca a été dit plus haut, que la présence de cette methode dans la classe Object est plus que discutable.
Marsh Posté le 20-02-2012 à 12:49:17
Bonjour les gens,
J'ai un problème à vous soumettre concernant le instanceof. Pour le moment, je ne vois pas comment faire autrement.
Données du problème :
J'ai une class A. (code figé)
J'ai une classe B extends A. (code figé)
J'ai une classe C (structure et héritage figés) avec une méthode "doMyWork" (signature figée) appelée par un environnement au code figé.
Ma méthode "doMyWork" prend en paramètre un Set<A> et doit faire un traitement sur tous les B.
Dernière info : je n'ai pas le droit de modifier l'architecture existante : je dois me débrouiller dans cette classe.
Dans le code, je boucle sur mon set, et pour chaque (elt instanceof B), j'effectue mon action.
J'utiliserai bien une autre écriture de mon test, mais quel en serait l'avantage par rapport à l'opérateur natif ?
Est-ce juste parce que ça ne paraît pas propre ou y a-t-il une vraie raison technique derrière ?
Quel danger instanceof représente ?
Quel perte de performance entraine son utilisation ? (a-t-elle été mesurée ? dans quelles conditions ?)
Une foix transformé en ByteCode, comment êtes-vous certains de la différence que fait "un code équivalent" à instanceof ?
Quelqu'un peut-il justifier un autre choix ?
Dernière remarque : lorsque vous n'êtes pas maître de l'architecture et que vous ajoutez une crotte de mouche sur le dos d'un éléphant ...
Alors attention aux critiques rapides svp.
Marsh Posté le 20-02-2012 à 14:43:13
Techniquement, il n'y a aucun problème à utiliser "instanceof". C'est parfaitement sûr et fiable, et ça ne pose pas de problème particulier niveau perf. C'est même certainement le moyen le plus performant de tester si un objet est bien une instance d'une classe donnée (le compilateur JIT de la VM est souvent capable d'optimiser ça, au contraire des méthodes à base de .getClass().getName() ou autre)
Le problème qu'il peut y avoir, c'est que son utilisation peut révéler une mauvaise conception de son logiciel (par exemple, une mauvaise exploitation du polymorphisme). Mais quand il s'agit de s'interfacer avec un système qu'on ne contrôle pas, on fait ce qu'on peut pour que ça marche, même si ce n'est pas toujours très propre.
PS : c'est sympa de déterrer ce topic juste à temps pour qu'il puisse fêter son neuvième anniversaire
Marsh Posté le 22-02-2003 à 18:10:48
J'ai decouvert l'existence de cet opérateur il y a peu, mes profs s'étant bien gardé de m'en révéler l'existence (à juste titre je pense) pendant leurs cours de Java.
En fait je m'interroge beaucoup sur l'utilité de cet opérateur. Même si au premier abord il peut paraitre très pratique, je trouve son utilisation dangereuse et souvent contraire aux principes de POO.
Je me demande vraiment pourquoi les concepteurs du langage ont mis cet opérateur, alors si quelqu'un pouvait m'expliquer comment on peut s'en servir, sans tomber dans la bidouille ou flinguer le polymorphisme...