Java Génériques - Pont méthode?
Quelque chose appelé le "pont de la méthode" concept lié à Java Génériques m'a fait arrêter à un point et de réfléchir sur elle.
Btw, je sais seulement qu'il se produit à la
bytecode niveau et n'est pas disponible
pour l'utiliser.
Mais je suis impatient de connaitre le concept derrière le "pont de la méthode" utilisée par le compilateur Java.
Exactement ce qui se passe derrière les coulisses et pourquoi est-il utilisé?
Tout aider avec un exemple serait grandement apprécié.
Je ne peux pas l'expliquer plus clair: stas-blogspot.blogspot.com/2010/03/... (qui se trouve être le 1er de résultats sur google)
ouais...très bonne explication.
bonne trouver; j'ai ajouté qu'à ma réponse.
ouais...très bonne explication.
bonne trouver; j'ai ajouté qu'à ma réponse.
OriginalL'auteur sgokhales | 2011-02-15
Vous devez vous connecter pour publier un commentaire.
C'est une méthode qui permet à une classe de l'extension d'une classe générique ou de la mise en œuvre d'une interface générique (avec un béton de type de paramètre) pour être utilisé comme une crue de type.
Imaginez ceci:
Cela ne peut pas être utilisé dans sa forme brute, en passant par deux
Object
s pour comparer, car les types sont compilées dans la méthode de comparaison (contrairement à ce qu'il se passerait si un paramètre de type générique T, où le type seraient effacés). Donc à la place, derrière les coulisses, le compilateur ajoute un "pont de la méthode", qui ressemble à quelque chose comme ceci (s'il était source de Java):Le compilateur protège l'accès au pont de la méthode, l'application qui explicite les appels directement suite à une erreur de compilation. Maintenant, la classe peut être utilisé dans sa forme brute:
Pourquoi est-il nécessaire?
En plus de l'ajout de support pour l'utilisation explicite de raw types (qui est principalement pour la rétro compatibilité) pont méthodes sont également requis pour le type de support à l'effacement. Avec le type d'effacement, une méthode comme ceci:
est effectivement compilé en bytecode compatibles avec le présent:
Si le pont méthode n'existait pas et que vous avez passé un
List<Integer>
et unMyComparator
à cette fonction, l'appel à la ligne taggedIMPORTANT
échouerait depuisMyComparator
aurait pas de méthode appeléecompare
qui prend deuxObject
s...que celui qui prend deuxInteger
s.La FAQ ci-dessous est une bonne lecture.
Voir Aussi:
qu'est-ce que "est égal à(T o)"?
Supposons que vous avez une méthode
Object get()
puis remplacer dans une sous-classe avec, disons,String get()
. La JVM ne remplacent correspondant exactement les signatures, y compris le type de retour. Donc javac crée un synthétique pont méthodeObject get()
(un.k.un.get()Ljava/lang/Object;
) avec une mise en œuvre qui appelleString get()
(un.k.un.get()Ljava/lang/String;
). Ceci n'a été possible dans le code source depuis la 1.5, et vous ne pouvez pas cibler une version antérieure de bytecode que le code source.Oui, c'est public, tel que rapporté par
javap -v MyComparator.class
. Cependant, comme je l'ai mentionné, le compilateur ne vous empêche d'appeler le pont méthode directement sur un type paramétré, donc je dirais que c'est "public avec une mise en garde". Si vous chercher à la sortie dejavap
, vous verrez que le pont de la méthode, malgré le fait d'avoirACC_PUBLIC
, dispose de deux options supplémentaires:ACC_BRIDGE
etACC_SYNTHETIC
. C'est ce que le compilateur va chercher à utiliser pour en interdire l'accès.Notez également que, ne signifie pas que tous pont méthodes sont publiques, à seulement une dans mon exemple. Si vous étiez extension d'une classe (et en lui donnant un type de béton) avec un protégé méthode générique, et l'a remplacée avec une méthode protégée, le pont de la méthode protégée de match.
OriginalL'auteur Mark Peters
Si vous voulez comprendre pourquoi vous avez besoin de pont méthode, vous comprendrez bien mieux ce qui se passe sans elle. Supposons qu'il n'y a pas de pont méthode.
Avis que, après l'effacement, la méthode
set
dansA
est devenupublic void set(Object newVal)
car il n'y a aucune limite sur le Type de paramètreT
. Il n'y a pas de méthode dans la classeB
la signature de ce qui est la même queset
dansA
. Donc, il n'y a pas de remplacement. Donc, quand quelque chose comme ce qui s'est passé:Polymorphisme ne marchera pas ici. Rappelez-vous, vous devez remplacer la méthode de la classe mère des enfants de la classe de sorte que vous pouvez utiliser la classe parent var pour déclencher le polymorphisme.
Ce pont méthode n'est silencieusement remplacer la méthode de la classe parente avec toutes les informations à partir d'une méthode avec le même nom mais une signature différente. Avec l'aide du pont de la méthode, le polymorphisme travaillé. Bien que sur la surface, vous remplacer le parent méthode de classe avec une méthode de signature différente.
OriginalL'auteur ch48h2o
C'est insteresting à noter que le compilateur déduit que
MyComparator
'méthode:est d'essayer de remplacer
Comparator<T>
'sdu type déclaré
Comparator<Integer>
. Sinon,MyComparator
'scompare
serait traité par le compilateur comme une (surcharge), et pas overridding, méthode. Et en tant que telle, elle n'aurait pas du pont de la méthode créée pour lui.OriginalL'auteur Callistus