9
votes

INTEGER.CLASS ET INT -CLASS

Comment cette déclaration Java compilait-elle sans avertissements?

Integer.class != int.class


5 commentaires

La déclaration de int.class est la suivante: Classe finale statique publique Type = (Classe ) CLASS.GETPRIMITIVECLASS ("INTE"); depuis le paramètre type N'est pas vraiment important et c'est encadré, c'est passable.


@Bestssss: la valeur est en boîte mais d'autres propriétés de la classe ne sont pas tenues. Par exemple, on peut utiliser la réflexion pour construire un integer à l'aide de integer.class mais il n'y a aucun moyen de le faire avec int.class .


Vous ne pouvez pas construire un int via réflexion, c'est une primitive. La décision est assez simple: les primitives sont en boîte, donc partout où vous pouvez passer un int, un entier ferait (ou vice-vers). Il existe une exception près: les paramètres de classe simples sont totalement différents, réflexes comme getMethod ("xxx", integer.class) ne fonctionneront pas pour xxx (int x) .


Je comprends que les primitives sont différentes, c'est pourquoi cela semble gênant. int.class n'est ni une superclasse ni une sous-classe de INTEGER.CLASS , INTEGER.CLASS.ISAssignABLEDFROM (INT.CLASS) == FAUX et int.Class.Cast (0) jette un ClasscastException . Je ne vois rien qui puisse être fait en utilisant int.class qui concerne la classe .


La classe est définitive (et ne dispose pas de sous-classes), la seule magie de la compilation de la compilée de paramètre, elle est perdue pendant l'exécution et la boxe permet une interopérabilité entre les primitives et les emballages. Étant donné que les types de paramètres ne peuvent pas être primitifs, la classe de la boîte est utilisée. C'est tout. Pour l'enregistrement, je crois que l'autoboxyture était inutile et la plupart des types de retour génériques (de côté co-variantes) n'ont pas amélioré la langue, en 20 ans et plus de programmation, j'ai eu 2 fois "ClasscastException": une fois B / C à l'aide d'ajouter Au lieu d'Addall, c'est-à-dire une autoocomplète et l'autre en raison d'une mauvaise importation. En tapant tous les <...> juste rendre le code illisible


3 Réponses :


4
votes

en raison de AutoBoxing . Vous ne pouvez pas utiliser les primitives dans les paramètres de type comme de type, de sorte que la primitive est en boîte dans l'emballage.


9 commentaires

Ne voyez pas pourquoi cela nécessiterait également de l'autoboxage sur les littéraux de classe.


Cela ressemble à une solution de contournement, car vous ne pouvez pas avoir la classe . Bien sûr, vous pouvez utiliser classe


En effet, semble être un piratage, et je ne vois aucune raison pour que classe ne suffirait pas. Voir mon commentaire ci-dessus - INTEGER.CLASS ET INT.CLASS N'EST MÊME N'EST MÊME SIMALEMENT SIMPLEMENTAIRE.


@Bozho, si vous utilisez la classe Vous ne pouvez rien déclarer comme t )


@Bestssss: dans quel scénario est-ce utile pour int.class ? Il n'y a aucun moyen de renvoyer une primitive int pour un type de retour générique.


@casablanca, mais vous pouvez faire INT int n = xxx (int.class) , la signature est trop simplifiée, mais elle pourrait être (classe Clazz, t x) et être appelé comme xxx (int.class, 10) .


@Bestssss: Vous ne pouvez pas passer des primitives pour des types génériques. Le 10 de votre exemple est autoboxé dans un intégrité et non passé comme un int .


@casablanca, ni le type de retour n'est un «INT», la raison est de garder une interopérabilité, le point est que vous ne pouvez pas faire cela si INT.Class était la classe


@Bestsss: interopérabilité avec quoi, cependant? Je ne vois pas une situation où on veut explicitement passer int.class lors de la gestion des génériques de toute façon. Si vous pouvez poster une réponse avec un exemple montrant comment cela peut être utile, j'accepterai volontiers votre réponse.



4
votes

Je ne crois pas que cela a quelque chose à voir avec autoboxyage.

Cela fait partie des règles des génériques qu'il traite les types primitifs comme leurs wrappers.


1 commentaires

Est-ce quelque part spécifié dans les JLS?



8
votes

Après beaucoup de recherches, je suis tombé sur ce petit bout dans les JLS, 15.8.2 classe littéraux:

Si p est le nom d'un type primitif, soit B le type d'une expression de type p après la conversion de boxe (§5.1.7). Ensuite, le type de p.class est classe .

La spécification n'explique pas pourquoi il en est ainsi, au lieu de par exemple. J'ai aussi pu trouver aucune preuve que ce soit est liée à des médicaments génériques ou autoboxing.

Entier est un objet de première classe alors que int est un type primitif, et la plupart des procédés de tel que isInstance < / code>, IsAssignableFrom et cast qui fonctionnent sur s ne sont pas valides dans le contexte de int.class . Par conséquent, je ne vois aucune raison pour laquelle le type de int.class est .


0 commentaires