0
votes

Pourquoi est-il redondant de jeter les deux arguments d'un appel de la fonction en Java si les paramètres de fonction sont le même type?

Je suis curieux de savoir comment casting fonctionne dans les appels de fonction. J'ai deux surcharges d'une fonction spécifique dans ma classe appelée exécuter code>. La première surcharge est la mise en œuvre de la base et accepte les paramètres de type code> double code>. La deuxième surcharge accepte les paramètres de type int code>. La deuxième surcharge appelle également la surcharge de base et le fait en casting des paramètres à double code>.

L'implémentation de base ressemble à ceci: p>

public int execute(int leftVal, int rightVal) throws IOException {
    return (int) execute((double) leftVal, (double) rightVal);
}


3 commentaires

Qui vous a dit que les moulages sont redondants? Ils ne sont pas si vous souhaitez réellement que la méthode INT appelle la double méthode.


@Sweeper L'IDE J'utilisais. J'ignore habituellement toutes les idées de syntaxe qu'il offre s'ils sont sucres , mais cela a été coincé parce que cela ne sonne pas comme ça devrait fonctionner.


Oh, tu voulais dire un des couts étaient redondants? Vous pouvez enlever l'une des coulées, mais pas les deux.


3 Réponses :


-1
votes

Vous pouvez comprendre que la nature de la surcharge est la liaison anticipée et le compilateur vérifie que la liaison est une fonction appropriée dans le compilateur.


0 commentaires

6
votes

Suppression de l'une ou l'autre des cases fonctionnera toujours, car dans un contexte d'invocation, une conversion primitive d'élargissement est autorisée. Donc non, Java pas aussi strict sur les types que vous pensiez :)

Selon la spécification de langue Java §5.3 Contexte d'invocation

Les contextes d'invocation permettent une valeur d'argumentation dans une méthode ou un constructeur Invocation (§8.8.7.1, §15.9, §15.12) à affecter à un correspondant paramètre formel.

Les contextes d'invocation stricts permettent d'utiliser l'une des opérations suivantes:

  • une conversion d'identité (§ 5.1.1)

  • conversion primitive d'élargissement (§ 5.1.2)

  • une conversion de référence d'élargissement (§ 5.1.5)

    Une "conversion primitive d'élargissement" est ... ( §5.1.2 )

    19 conversions spécifiques sur les types primitifs sont appelés élargissement Conversions primitives:

    • octet à court , int , long , float , ou double

    • court à int , long , float ou double

    • char à int , long , float ou double

    • int à long , float ou double

    • long à float ou double

    • float à double

      int à double est l'une des conversions ci-dessus et est donc autorisée lorsque vous appelez une méthode. D'autre part, double à int est une conversion primitive de rétrécissement, qui n'est pas autorisée dans un contexte d'invocation. Cela explique pourquoi le (double, double) est sans ambiguïté appelé.


2 commentaires

Oh, cela a beaucoup de sens. Donc, je suppose que si je l'ai fait dans l'ordre inverse, je n'aurais pas le même comportement et je dois jeter explicitement chaque double sur un type INT.


@kohai si par "ordre inverse", vous voulez rendre le (double, double) méthode appelez la méthode (int, int) , puis oui, vous avez raison.



1
votes

Pourquoi ce qui précède, en particulier le (double) gauche, (double), une partie à droite, une redondance?

La distribution que vous avez faite ci-dessus est nécessaire pour que vous déclarez explicitement que vous souhaitez appeler ce niveau de base surchargé. Sinon, le code supposera simplement que vous souhaitez recueillir dans cette même méthode. Donc, oui, vous avez raison de dire "La première distribution aide le compilateur à déterminer la surcharge à choisir"

La deuxième coulée est donc implicite. Peut-être parce que les types sont primitifs faciles à couler?

Donc, si vous allez d'un type primitif nécessitant une quantité de bits inférieure ( int est de 32 bits) à un type primitif pouvant accueillir une plus grande quantité de bits ( Double est 64 bits), Java sait de le faire au moment de l'exécution. Toutefois, si vous allez d'un double (64 bits) sur un int (32 bit), vous en tant que développeur besoin de couler explicitement puisque vous pouvez rencontrer Perte d'information ici . C'est pourquoi celui-ci (int) est nécessaire sur le retour; Vous allez d'un double à un int qui peut être la perte.

Quelque exemple de code: xxx xxx xxx

J'ai toujours pensé que Java était très strict sur des types explicitement identifiant

Les primitives sont une caractéristique beaucoup plus nuancée de la langue Java. Je pense que par des types, vous vous référez implicitement à objet en Java. Vous avez raison que Java est beaucoup plus strict en ce qui concerne le casting objet. Si nous prenons l'exemple ci-dessus et utilisons les objets entier et integer , ils ne compileront pas, et signalera un avertissement ne peut pas casser java.lang.long à Java .lang.Integer ;

EXEMPLES qui ne compilera pas en raison de la coulée non valide xxx xxx < / pré>

ps: il est standard de se référer à toutes les fonctions avec le même nom de méthode que surchargé; pas commun à faire référence à une méthode comme "base" et dites la surcharge de repos cette méthode


1 commentaires

Configurez ceci comme réponse acceptée car il s'agit d'un meilleur travail expliquant pourquoi l'élargissement et la réduction des conversions primitives sont distinguées. En outre, vous avez souligné la nuance des primitives en Java opposée aux types d'objets. Et vous avez répondu à toutes mes questions de manière très concise. Merci cela explique beaucoup, en fait. Et le PS Tidbit est très apprécié, lol.