In deze Code Workshop zullen we je kennis van Java Strings testen. Binnen de voorbeeldcode worden stringvariabelen verwerkt in een Java-klasse, die op zijn beurt een innerlijke klasse heeft. Als u wilt weten wat er gebeurt wanneer de code wordt uitgevoerd, moet u niet alleen de basisbeginselen van String begrijpen, maar ook de principes van objecten en klassen, evenals besturingsstructuren, waaronder methoden, loops en conditionals..
Wanneer u de code doorwerkt, onthoud dan dat de programmeur die het heeft geschreven fouten in hun logica kan hebben. De code bevat geen syntaxisfouten die tijdens runtime uitzonderingen veroorzaken, maar het resultaat hoeft niet noodzakelijk de bedoeling te zijn van de programmeur. Wanneer je aan een programmeerproject werkt, is de kans groot dat je uiteindelijk gaat werken met de code van iemand anders, of de code die je zelf ooit hebt geschreven en die je je nauwelijks kunt herinneren. Helaas hebben wij mensen de neiging om niet vaak perfecte code te produceren, dus lezen met een kritisch oog is essentieel.
De onderstaande Java-code staat voor een bestand in de Java-klasse met daarin een innerlijke klasse. In de code ondergaan tekstreeksvariabelen verschillende processen. Wat gebeurt er wanneer de StringFun-constructormethode wordt uitgevoerd? Werk de code door en noteer wat u denkt dat zal worden uitgeschreven via de systeemuitvoerverslagen op de punten A, B, C, D, E en F, rekening houdend met het feit dat een van deze meer dan eens kan worden uitgevoerd. Misschien vindt u het het gemakkelijkst om een potlood en papier te gebruiken om op te merken wat er gebeurt als de code vordert.
public class StringFun public StringFun () String initString = "abcdefghij"; StringWorker strWorker = nieuwe 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? TheStr.substring (0, endPosn): theStr); System.out.println ("PUNT 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; maxLengte = 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); voor (int i = 0; i
De oplossing
Dit is wat wordt uitgevoerd wanneer de constructormethode StringFun wordt uitgevoerd:
PUNT F: abcdefghij PUNT E: abcdefghij PUNT A: abcdefghij PUNT F: abcdefghij PUNT B: abcdefghijabcdefghij PUNT C: abcde PUNT D: abcdeabcdefghijabcdefghijLet op welke String-variabele wordt uitgeschreven in elke instructie - soms is dit de instantievariabele en soms is het een lokale variabele. Als dit niet overeenkomt met wat je dacht dat output zou zijn, maak je geen zorgen. De code is opzettelijk lastig. Als je de output goed hebt, goed gedaan!
Aantekeningen en uitleg
Het bijgevoegde bronbestand bevat de volledige code met annotaties die uitleggen wat er gebeurt tijdens de uitvoering. U kunt een beter inzicht krijgen door het programma te compileren en uit te voeren en extra traceerinstructies toe te voegen als u vindt dat dit helpt (voeg het Java-bronbestand aan een project toe en maak een objectinstantie van de klasse StringFun om te beginnen).
Laten we een paar van de probleemgebieden hier bespreken.
Onveranderlijkheid
In de StringWorker-constructormethode wordt de methode "shortenString" aangeroepen. Hoewel deze methode de substringmethode op de instantievariabele String noemt, verandert deze de waarde ervan niet echt. In Java zijn strings onmogelijk. Dit betekent dat wanneer u een tekenreeks wijzigt, Java eigenlijk een nieuwe reeks maakt. De substringmethode wijzigt de tekenreeks waarop deze wordt aangeroepen niet, maar kopieert de inhoud naar een nieuwe tekenreeks met de substringwijziging toegepast, waarbij deze nieuwe tekenreekswaarde wordt geretourneerd. Als de substring-methode aanroep als volgt is gewijzigd:
theText = theText.substring (0, maxLength);Het resultaat zou anders zijn, omdat de instantievariabele zou worden bijgewerkt om de nieuwe subtekenreeks te bevatten. Als de code staat, retourneert de methode 'abcde' maar doet daar niets mee.
Parameters en retouren
Een ander mogelijk lastig onderdeel van de code is de "multiplyText" -methode. De verwarring hier wordt veroorzaakt doordat de methode een ongepaste naam heeft en niet op de juiste manier wordt gebruikt. Als u, in plaats van de inhoud van de methode door te werken, een intuïtieve interpretatie van deze methode hebt gemaakt, zou u aannemen dat het doel ervan zou zijn om de tekst te vermenigvuldigen met het getal dat is doorgegeven als een integer-parameter. In feite voegt de methode de tekst vele malen aan zichzelf toe, wat betekent dat het zelf nog één keer "tijden" oplevert dan je zou verwachten. Methodenamen kunnen van grote invloed zijn op hoe bruikbaar een Java-bibliotheek of -programma is, evenals namen van variabelen en klassen.
De methode "multiplyText" wordt tweemaal in de code genoemd, eenmaal in de StringFun-constructor en eenmaal in de StringWorker-constructor. In de StringWorker-constructor doet de code niets met de geretourneerde tekenreeks en dus doet de methode-aanroep feitelijk niets. De "multiplyText" -methode verandert de instantievariabele String niet. Het voert wijzigingen uit op een doorgegeven String en retourneert het resultaat als een nieuwe tekenreeks. Wanneer de methode "multiplyText" wordt aangeroepen in de constructor StringFun, doet de code dit keer iets met het resultaat - het stelt de instantie-variabele StringWorker in op de geretourneerde tekenreeks, met behulp van de "setText" -methode.
Deze verwarringen zijn niet alleen een indicator voor het ongepast gebruiken van een methode, maar een teken dat de methode zelf waarschijnlijk slecht is ontworpen en benoemd. Met de methode "shortenString" wordt de klasse-instantie-variabele gewijzigd, terwijl de "multiplyText" -methode geen invloed heeft op de instantievariabele. Of een van deze twee of beide geschikt zijn, hangt af van het doel van de klas binnen de toepassing, maar hun namen moeten hun doel weerspiegelen op een manier die intuïtief is om te begrijpen.
Welke variabele?
De andere algemene bron van verwarring in de code is het feit dat we te maken hebben met verschillende klassen- en lokale variabelen. Als u bijvoorbeeld kijkt naar de sectie in de StringFun-constructor waar we een nieuwe lokale variabele met de naam "endString" maken, ziet u dat deze de verwerking uitvoert op een variabele met de naam "theStr" die een paar regels eerder is gemaakt. Gegeven de verwerking die plaatsvindt tussen deze twee secties, mag u intuïtief verwachten dat de sectie "endString" de zojuist gewijzigde instantieobjectvariabele StringWorker verwerkt in plaats van een eerdere lokale variabele. De code lijkt daarom contra-intuïtief, maar nogmaals, dergelijke interpretaties worden belemmerd door het ontbreken van commentaar dat het doel van beide klassen of een van de variabelen aangeeft.
Conclusie
OK, dus de code had een paar trucjes erin. Dit moet echter de realiteit weerspiegelen van het werken aan veel Java-projecten. Zelfs met de beste bedoelingen bevat de meeste code fouten. Programmeringsprojecten zijn vaak onderhevig aan planningswijzigingen die uiteindelijk resulteren in misleidende logica en variabele en methodamen die verwarrend lijken. Als de code slecht wordt becommentarieerd of helemaal niet wordt becommentarieerd zoals in het bovenstaande voorbeeld, maakt dit de zaken alleen maar erger.
De mogelijkheid om realistisch code te lezen en praktische maatregelen te gebruiken, zoals trace-instructies om te zien wat er op verschillende punten tijdens de uitvoering gebeurt, is een echte aanwinst in elk programmeringsproject, net als het begrijpen van de taalstructuren..