Dans cet atelier de code, nous testerons vos connaissances de Java Strings. Dans l'exemple de code, les variables String vont être traitées dans une classe Java, qui à son tour possède une classe interne. Pour bien comprendre ce qui se passera lorsque le code sera exécuté, vous devez comprendre non seulement les bases de String, mais également les principes des objets et des classes, ainsi que les structures de contrôle, y compris les méthodes, les boucles et les conditions..
Lorsque vous travaillez dans le code, rappelez-vous que le programmeur qui l'a écrit peut avoir des erreurs dans sa logique. Le code ne contient aucune erreur de syntaxe pouvant générer des exceptions lors de l'exécution, mais le résultat ne correspond pas nécessairement à ce que le programmeur avait prévu. Lorsque vous travaillez sur un projet de programmation, il y a de fortes chances que vous finissiez par travailler avec le code de quelqu'un d'autre, ou le code que vous avez vous-même écrit à un moment donné dans le passé et dont vous vous souvenez à peine. Malheureusement, nous, humains, avons tendance à ne pas produire très souvent un code parfait. Il est donc essentiel de lire avec un œil critique..
Le code Java ci-dessous représente un fichier de classe Java contenant une classe interne. Dans le code, les variables text String subissent plusieurs processus différents. Que se passe-t-il lorsque la méthode du constructeur StringFun s'exécute? Parcourez le code et notez ce que vous pensez être écrit dans les instructions de sortie du système aux points A, B, C, D, E et F, tout en gardant à l'esprit que ces opérations peuvent être exécutées plusieurs fois.. Vous trouverez peut-être plus facile d'utiliser un crayon et du papier pour noter ce qui se passe à mesure que le code progresse.
classe publique StringFun public StringFun () String initString = "abcdefghij"; StringWorker strWorker = new StringWorker (initString); String theStr = strWorker.getText (); System.out.println ("POINT A:" + theStr); strWorker.setText (strWorker.multiplyText (1, theStr)); System.out.println ("POINT B:" + strWorker.getText ()); int endPosn = initString.length () / 2; String endString = (theStr.length ()> endPosn? TheStrsubstring (0, endPosn): theStr); System.out.println ("POINT C:" + endString); String anotherString = endString.concat (strWorker.getText ()); System.out.println ("POINT D:" + anotherString); public class StringWorker private String theText; private int maxLength; public StringWorker (String initText) theText = initText; longueur maximale = 5; shortenString (); multiplyText (2, theText); System.out.println ("POINT E:" + theText); private void shortenString () if (theText.length ()> maxLength) theText.substring (0, maxLength); public String multiplyText (int multBy, String multText) StringBuilder sBuild = new StringBuilder (multText); pour (int i = 0; i
La solution
Voici ce qui est généré lorsque la méthode du constructeur StringFun s'exécute:
POINT F: abcdefghij POINT E: abcdefghij POINT A: abcdefghij POINT F: abcdefghij POINT B: abcdefghijabcdefghij POINT C: abcde POINT D: abcdeabcdefghijabcdefghijRemarquez quelle variable String est écrite dans chaque instruction. Parfois, il s'agit de la variable d'instance et parfois, d'une variable locale. Si cela ne correspond pas à ce que vous pensiez être une sortie, ne vous inquiétez pas. Le code est intentionnellement délicat. Si vous avez la sortie correcte, bien fait!
Notes et explications
Le fichier source joint contient le code complet avec des annotations expliquant ce qui se passe pendant l'exécution. Vous pouvez acquérir une meilleure idée en compilant et en exécutant le programme et en ajoutant des instructions de trace supplémentaires (aidez-nous à ajouter le fichier de classe Java source à un projet et à créer une instance d'objet de la classe StringFun)..
Passons en revue certains des points chauds ici.
Immutabilité
Dans la méthode du constructeur StringWorker, la méthode "shortenString" est appelée. Bien que cette méthode appelle la méthode de sous-chaîne sur la variable d'instance String, elle ne modifie pas réellement sa valeur. En Java, les chaînes sont immuables. Cela signifie que lorsque vous modifiez une chaîne, Java crée une nouvelle chaîne. La méthode de sous-chaîne ne modifie pas la chaîne sur laquelle elle est appelée, mais copie son contenu dans une nouvelle chaîne avec la modification de sous-chaîne appliquée, en renvoyant cette nouvelle valeur de chaîne. Si l'appel de la méthode de sous-chaîne a été modifié comme suit:
theText = theText.substring (0, maxLength);Le résultat serait différent, car la variable d'instance serait mise à jour pour contenir la nouvelle sous-chaîne. En l'état actuel du code, la méthode retourne "abcde" mais ne fait rien avec elle.
Paramètres et retours
Une autre partie potentiellement délicate du code est la méthode "multiplyText". La confusion ici est due à la fois au fait que la méthode a un nom inapproprié et qu’elle n’est pas utilisée de manière appropriée. Si, plutôt que de travailler à travers le contenu de la méthode, vous preniez une interprétation intuitive de cette méthode, vous supposeriez que son objectif serait de multiplier le texte par le nombre passé en tant que paramètre entier. En réalité, la méthode ajoute le texte à lui-même plusieurs fois, ce qui signifie qu'il en résulte un "temps" de plus que ce à quoi vous pourriez vous attendre. Les noms de méthodes peuvent avoir un impact considérable sur la facilité d'utilisation d'une bibliothèque ou d'un programme Java, tout comme les noms de variable et de classe..
La méthode "multiplyText" est appelée deux fois dans le code, une fois dans le constructeur StringFun et une fois dans le constructeur StringWorker. Dans le constructeur StringWorker, le code ne fait rien avec la chaîne retournée et l'appel de méthode ne fait donc rien. La méthode "multiplyText" ne modifie pas la variable d'instance String. Il effectue des modifications sur une chaîne passée et renvoie le résultat sous la forme d'une nouvelle chaîne. Lorsque la méthode "multiplyText" est appelée dans le constructeur StringFun, le code agit quelque chose avec le résultat - il définit la variable d'instance StringWorker sur la chaîne renvoyée, à l'aide de la méthode "setText"..
Ces confusions ne sont pas simplement un indicateur d'utilisation inappropriée d'une méthode, mais un signe que la méthode elle-même est probablement mal conçue et mal nommée. La méthode "shortenString" modifie la variable d'instance de la classe, tandis que la méthode "multiplyText" n'a aucun effet sur la variable d'instance. Que l'un ou les deux soient appropriés dépend de l'objectif de la classe au sein de l'application, mais leurs noms doivent refléter leur objectif de manière intuitive à comprendre..
Quelle variable?
L’autre source générale de confusion dans le code est le fait qu’il s’agit de plusieurs variables de classe et locales différentes. Par exemple, si vous examinez la section du constructeur StringFun dans laquelle nous créons une nouvelle variable locale nommée "endString", vous verrez qu'elle effectue le traitement sur une variable nommée "theStr" qui a été créée quelques lignes auparavant. Étant donné le traitement qui se produit entre ces deux sections, vous pouvez vous attendre intuitivement à ce que la section "endString" traite la variable d'instance d'objet StringWorker nouvellement modifiée plutôt qu'une variable locale antérieure. Le code semble donc contre-intuitif, mais là encore, de telles interprétations sont gênées par le manque de commentaires indiquant le but de l'une ou l'autre classe, ou de l'une des variables..
Conclusion
OK, le code contenait quelques astuces. Cependant, cela reflète la réalité du travail sur de nombreux projets Java. Même avec les meilleures intentions du monde, la plupart des codes contiennent des erreurs. Les projets de programmation sont souvent soumis à des changements de plan qui aboutissent à une logique trompeuse ainsi qu'à des noms de variable et de méthode qui semblent confus. Si le code est mal commenté, ou pas commenté comme dans l'exemple ci-dessus, la situation est encore pire.
Avoir la capacité de lire le code de manière réaliste et d'utiliser des mesures pratiques telles que les instructions de trace pour voir ce qui se passe à différents moments de l'exécution est un atout essentiel dans tout projet de programmation, tout comme la compréhension des structures de langage..