12
votes

Conscons-physique en Java en utilisant des annotations?

Y a-t-il une bibliothèque existante qui me permet d'annoter une méthode Java en tant que @Const, de sorte que le compilateur (à l'aide d'APT I présume) signaler une erreur si elle met à jour un champ ou invoque une méthode non- @ Const sur un champ; et annotez un paramètre comme @Const, de sorte que la méthode d'acceptation ne puisse invoquer aucune de ses méthodes non-const ou mettre à jour l'un de ses champs?

(essentiellement, essayer d'ajouter la constance à Java en utilisant des annotations; il y a . certains détails évidents ne sont pas couverts dans la question ci-dessus, par exemple confier à / d'un @ paramètre Const typé, etc)

Je l'ai trouvé ceci: http://confluence.atlassian.com/pages/viewpage.action?pageid=182158080 Mais il semble que ce soit seulement disponible Dans le cadre de l'idée.

Après une demande de clarification ci-dessous, voici un exemple de code pour montrer ce que je veux dire: xxx

maintenant, si je définis une méthode tels que: xxx

une ligne telle que: p.getname () serait ok dans processperson , puisque , car < Code> getname a été marqué comme une méthode @Const. Mais appelez p.setName () à partir de processPerson sera signalé comme une erreur.

Notez que ceci est très différent de finale < / code>: Si le paramètre a été défini comme Personne final P , toute affectation à p aurait été illégale, mais il est toujours parfaitement valide pour modifier ce que p < / code> fait référence à (en utilisant p.setname (...) ou même plus directement, avec p.name = ... .


9 commentaires

Avez-vous essayé d'utiliser le mot-clé de code final ? Qu'est ce qui ne va pas avec ça?


Une méthode finale est une méthode qui ne peut pas être remplacée. C'est différent.


Je veux dire pas la méthode finale. Je veux dire l'argument final. Je sais quelle méthode finale est :)


Un paramètre final signifie que la méthode ne peut pas réaffecter la référence; Mais cela peut toujours modifier l'objet que le paramètre se réfère. Qui est (a) pas ce que je cherche, et (b) totalement inutile (au moins à mon avis).


@M, ce n'est pas totalement inutile, mais il serait peut-être plus facile de voir ce que vous voulez alors dire si vous avez écrit un exemple de code?


Oui, tu as raison. Vous pouvez vraiment modifier l'objet en interne. Personnellement, j'utilise personnellement une solution incroyable pour ces tâches: s'il s'agit de la collection, je l'enveloppe à l'aide de Collection.unmodifireablelist () etc., s'il s'agit de ma propre classe I soit implémenter la logique qui ne permet pas de modifier la classe elle-même ou , mieux, enveloppez l'objet en utilisant l'aspect. L'aspect peut être mis en œuvre soit en utilisant l'un des cadres d'aspect (comme AspectJ) ou en utilisant un proxy dynamique. Je comprends vos souhaits d'avoir un cadre qui le fait automatiquement et vous souhaite bonne chance à en trouver un.


@ Thorbjørn: exemple de code ajouté à la question.


@ALEXR: Bien sûr, l'utilisation d'objets immuables est une excellente solution, mais pas toujours applicable. Et non vodiifiablelist () a un prix d'exécution. Ce que je cherche, c'est une solution pure compilée.


@M. Elkstein: Je pense que "oo sur des objets immuables" pourrait être quelque chose que vous pourriez être intéressé (mais, bien accordé, cela nécessite un décalage de Java idiosynchrases, comme des haricots et des ensembles;)


4 Réponses :


8
votes

0 commentaires

6
votes

Jetez un oeil à la Cadre de vérificateur , qui a essentiellement des dames qui tentent de détecter Défauts logiciels [JSR-305] via un système d'annotation de type extensible [JSR-308].

Il dispose d'un vérificateur d'immutabilité (2 en réalité) qui vous permet d'annoter le code avec des annotations d'immutabilité telles que @Mutable, @Imutable et @Readonly . Cet outil se différencie entre une instance immuable et une référence en lecture seule.

i love ce cadre et utilisez-le principalement pour la vérification null, mais j'essaie de commencer à utiliser le vérificateur d'immutabilité et vérificateur interne plus.

ANNOTATER UN PARAMETER AS @CONST, de sorte que la méthode d'acceptation ne puisse invoquer aucune de ses méthodes non-const, ou mettre à jour l'un de ses champs?

ressemblerait à: xxx

me permet d'annoter une méthode Java en tant que @Const, de sorte que le compilateur (à l'aide d'APT I présume) signaler une erreur si elle met à jour un champ ou invoque une méthode non- @ Const sur un champ; et

Cela ressemblerait à ceci pour l'exemple de la question suivante: xxx

the @Readonly indique le récepteur (le Cette instance dont la méthode est appelée) devrait pas être modifiée. Malgré le paramètre supplémentaire apparent, la méthode est toujours appelée comme d'habitude: xxx



1 commentaires

C'est parfait, merci! Je cherche quelque chose comme ceci depuis des siècles, si heureux de l'avoir enfin avec Java 8. Très puissante choses, avec un plug-in Eclipse et avec des plugins maven, fourmi, grades, etc. Plugins aussi, pour que quiconque intéressé. Une seule recommandation est que les annotations IGJ semblent beaucoup plus expressives que le vérificateur Javari pour toute personne confondue par le chevauchement des fonctionnalités. Javari devrait probablement être ignoré IMHO. (Aussi - Réponse modifiée pour corriger l'annotation du récepteur sur les méthodes.)



0
votes

Je suis deuxième commentaire @Alexr, cela peut être fait en utilisant AspectJ, quelque chose suivant ces lignes:

public aspect ConstAspect{
declare warning : withincode(* *(..,@Const (*),.. ) ) : "Calling Const Method..";
}


0 commentaires

-6
votes

const était en C ++. Java apparemment frappé à dessein. Et maintenant, les gens grandissent sans vraiment expérimenté const pensent que c'est une bonne idée.

Une fois que vous avez marqué une méthode comme Const , il se répandit comme le cancer, très bientôt, vous vous trouverez const presque tout. Il aurait été préférable d'avoir un non-const .

Tout à fait inutile. Cela ne fait que faire appel académiquement, n'aide personne dans de vrais programmes.


5 commentaires

C'est très très discutable. J'ai utilisé const beaucoup dans mes programmes C ++, et je ne me souviens pas de sa propagation. Le marquage gets en tant que const et faire des surcharges de const d'opérateurs d'accès (comme opérateur [] ) aide vraiment à prévenir les modifications accidentelles des objets.


Je pense que const est bon aussi (8 ans d'expérience C ++). Et sur la propagation - Que diriez-vous de la spécification d'exception sur une méthode? Il se propage comme le cancer, mais Java Devs réussit à vivre avec elle.


C'est une bonne chose la Const qui se propage "comme le cancer". Plus il est vrai que Const est correct la sécurité de votre code d'abus.


@Eliasvasylenko Je peux voir pourquoi il est irritant d'un point de vue codant, car il fait que les signatures ont l'air assez longtemps. Je dirais que les paramètres de méthode doivent toujours être traités comme const sauf indication explicite autrement comme mutable . Ensuite, vous pouvez rendre votre code moins verbose en améliorant la conception :).


@Navneeth absolument! Je suis complètement d'accord avec ça. Dans le contexte de la question cependant, je pense qu'il existe une tension entre vouloir choisir une défaillance raisonnable et que notre processeur d'annotation hypothétique soit optimisé plutôt que de désinscription. Personnellement, je voudrais éviter un système qui a changé la sémantique de mon code uniquement dans l'absence d'une annotation spéciale. Pour une langue non-Java ouais, je pense avoir un mot-clé pour la mutabilité serait un meilleur choix. Et avoir des champs être privés et finaux par défaut, etc ...