32 votes

Comment déterminer si une méthode Java modifie un objet passé en paramètre

Je viens d'une C++ fond et je suis actuellement en apprentissage de Java. Une question s'est posée lorsque j'ai essayé d'utiliser certains des bibliothèques tierces. Comment puis-je déterminer si l'appel à une méthode de prendre un objet de référence comme paramètre modifie l'objet? En C++ c'est clair grâce à l'utilisation du mot-clé const. Si la signature de la méthode est:

void foo(Boo& boo);

Je sais que l'objet référencé peut être modifié, alors que si la signature de la méthode est:

void foo(const Boo& boo);

Le compilateur garantit que l'objet référencé n'est pas modifié.

Je n'ai pas vu quelque chose d'analogue en Java, comme seule la référence elle-même peut être déclarée final, pas de l'objet référencé, et un dernier argument n'a pas beaucoup de sens, en premier lieu, puisqu'il est passé par valeur, de toute façon. Donc, quand je vois une méthode telle que:

void foo(Boo boo) {...}

Comment puis-je déterminer si l'objet référencé par boo est modifié à l'intérieur du corps de la fonction (peut-être à l'aide d'annotations)? Si il n'y a aucun moyen de savoir, est-il largement utilisé convention ou de certaines des meilleures pratiques pour éviter la confusion et d'erreurs?

26voto

Peter Lawrey Points 229686

comment puis-je déterminer si l'objet référencé par boo est modifié à l'intérieur du corps de la fonction (peut-être à l'aide d'annotations)?

Le seul moyen est de lire le code, malheureusement.

Si il n'y a aucun moyen de savoir, est-il largement utilisé convention ou de certaines des meilleures pratiques pour éviter la confusion et d'erreurs?

La convention commune est de passer un objet qui ne peut pas être modifié, à l'aide d'un wrapper en cas de besoin. C'assurer que la classe ne peut pas modifier l'objet.

List<String> readOnly = Collections.unmodifiableList(list);

Si l'objet est Clonable, vous pouvez également utiliser clone() mais une autre approche est d'utiliser une copie.

List<String> readOnly = new ArrayList<>(list);

Si vous vous souciez de tels comportements, les tests unitaires peuvent montrer si une méthode modifie un objet ou non. Si vous avez des tests unitaires déjà, il est généralement une ou deux lignes supplémentaires pour vérifier cela.

14voto

Mureinik Points 61228

Malheureusement, il n’existe aucune installation de ce type dans la langue. Une bonne pratique défensive consiste à définir les objets de données que vous transmettez comme étant immuables (c'est-à-dire sans aucune méthode publique permettant de modifier leur état). Si cela vous préoccupe vraiment , vous pouvez copier / cloner un objet avant de le transmettre à une méthode en laquelle vous n’avez pas confiance, mais il s’agit généralement d’une précaution redondante.

8voto

NOTE: cette réponse est une version plus détaillée de

Vous pouvez également écrire à la pureté ou des effets secondaires des annotations dans votre code - mernst

Il existe le Vérificateur de Cadre parmi les diverses choses qu'il peut vérifier au moment de la compilation via des annotations est l' IJG Immutablity vérificateur. Cette checker vous permet d'annoter les références de l'objet avec @Immutable ou @ReadOnly.

Le problème est que souvent, vous auriez à annoter la bibliothèque vous-même. Pour faciliter votre tâche, le Vérificateur Cadre peut automatiquement déduire une partie des annotations; vous aurez encore beaucoup à faire vous-même.

6voto

mernst Points 448

Un effet secondaire de l'analyse n'est pas intégré dans le langage Java.

Vous pouvez effectuer des effets secondaires l'analyse par l'inspection manuelle, mais plusieurs outils existent pour automatiser le processus.

Vous pouvez utiliser un outil d'inférence (1, 2, 3) pour détecter si votre code d'effets secondaires d'un paramètre.

Vous pouvez également écrire à la pureté ou des effets secondaires des annotations dans le code, et ensuite utiliser un contrôle/vérification de l'outil (1, 2) pour s'assurer que le code est conforme aux annotations que vous avez écrit.

Tous ces outils liés ont des limites, mais vous pourriez trouver utiles. Si vous connaissez d'autres outils, de les mentionner dans les commentaires.

4voto

TAsk Points 7431

Comment puis-je déterminer si l'objet référencé par boo est modifié à l'intérieur de le corps de la fonction (peut-être à l'aide d'annotations)?

Je suis d'accord avec les autres réponses qu'il n'existe aucun moyen direct pour déterminer cette méthode permettra de modifier votre objet ou non et oui à assurez-vous que la méthode ne peut pas modifier votre Object vous tous avez à faire c'est de votre côté.

Si il n'y a aucun moyen de savoir, est-il largement utilisé convention ou quelques bonnes pratiques pour éviter la confusion et d'erreurs?

Ici le nom de la méthode vient de la scène. Aller de l'avant avec la convention de nommage de la méthode que nous avons de prendre un coup d'oeil à certaines des déclarations de méthode qui, clairement, de vous convaincre que votre Object ne sera pas du tout changé.

Par exemple, Vous savez qu' Arrays.copyOf pas de changement de votre tableau réel, System.out.println(boo) ne changera pas votre boo

Les noms de méthodes sont de véritables armes de fournir autant d'informations que possible à la méthode de l'utilisateur.(Oui! c'est toujours pas possible, mais tout à fait une bonne pratique à suivre.)

Nous allons considérer dans votre cas, que dire printBoo ne imprimer, copyBoo ne copie, clearBoo permettra de réinitialiser tous les attributs, checkAndCreateNewBoo vérifiera votre boo Object et en créer de nouveaux si nécessaire.

Donc, en définitive, si nous pouvons les utiliser de manière adéquate, l'appelant peut être assurée avec le fait qu' Object resteront les mêmes après l'appel de la méthode.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X