Java-methoden en programmadecompositie
return. Ontdek waar je elke variabele kunt gebruiken, waarom een methode met kopieën van haar argumenten werkt en hoe de aanroepstack bijhoudt welke methoden worden uitgevoerd. Overlaad methoden en voorspel welke versie Java aanroept. Verdeel ten slotte een probleem in kleine methoden die elk één ding doen, verwijder herhaalde code en bouw en test een programma methode voor methode.BeginnerLes 3 van 11 in Cursus Java programmeren: klassen, overerving, collecties en streams
Wat je leert
- Definieer statische methoden, roep die aan vanuit
mainen vanuit andere methoden, en geef ze via parameters de informatie die ze nodig hebben.- Definieer een methode en roep die aanSchrijf een methodekop en methodebody op de juiste plaats, roep de methode aan met haar naam en volg hoe de uitvoering naar de methode springt en terugkeert.
- Geef informatie door aan een methode via parametersDeclareer parameters met een type en een naam, roep de methode aan met passende argumenten en gebruik meerdere parameters in de juiste volgorde.
- Definieer een methode en roep die aan
- Schrijf methoden die een waarde berekenen en die met
returnteruggeven, en gebruik retourwaarden in variabelen, expressies en voorwaarden.- Geef een waarde terug en gebruik dieDeclareer een retourtype, stuur een resultaat terug met een return-instructie en bepaal in de aanroepende code wat er met de retourwaarde gebeurt.
- Gebruik return binnen voorwaardelijke instructies en lussenGebruik return-instructies binnen if-instructies en lussen, zorg dat elk pad een waarde teruggeeft en schrijf methoden die een ja-neevraag beantwoorden.
- Geef een waarde terug en gebruik die
- Weet waar je elke variabele kunt gebruiken, wat een methode wel en niet kan veranderen in de code die haar aanroept en hoe de aanroepstack bijhoudt welke methoden worden uitgevoerd.
- Bepaal waar je elke variabele kunt gebruikenPas de bereikregels toe voor lokale variabelen, parameters en variabelen die in blokken zijn gedeclareerd, en herstel compilatiefouten die door fouten in het bereik ontstaan.
- Begrijp dat argumentwaarden als kopieën worden doorgegevenVoorspel wat een methode kan veranderen in de code die haar aanroept: de methode werkt met kopieën van de argumentwaarden, dus een parameter een nieuwe waarde geven verandert de variabele van de aanroepende code niet.
- Volg methodeaanroepen op de aanroepstackVolg hoe Java methoden die worden uitgevoerd in stackframes bijhoudt, volg programma’s waarin methoden andere methoden aanroepen en lees een stacktrace.
- Bepaal waar je elke variabele kunt gebruiken
- Geef meerdere methoden dezelfde naam met verschillende parameterlijsten en voorspel welke versie Java aanroept voor een gegeven verzameling argumenten.
- Schrijf overladen methodenDeclareer methoden met dezelfde naam, weet welke verschillen een geldige overladen methodevariant opleveren en gebruik overladen wanneer de methoden dezelfde taak uitvoeren.
- Voorspel welke overladen methode wordt uitgevoerdBepaal welke versie Java kiest op basis van de typen van de argumenten, inclusief automatische verbredende typeconversie, en herken aanroepen die niet compileren.
- Schrijf overladen methoden
- Verdeel een probleem in kleine methoden die elk één ding doen, vervang herhaalde code door methoden met parameters en bouw en test een programma methode voor methode.
- Geef elke methode één duidelijke taakHerken een goed ingedeeld programma, splits code die te veel doet en houd berekeningen gescheiden van invoer en uitvoer.
- Vervang herhaalde code door een methode met parametersZoek code die met kleine verschillen wordt herhaald, maak er één methode van waarvan de parameters de verschillen doorgeven en controleer of het programma zich nog hetzelfde gedraagt.
- Ontwerp een programma top-down en test het methode voor methodePlan een programma als een reeks methodeaanroepen, schrijf het stap voor stap met tijdelijke stubs en test elke methode met invoer waarvan je de resultaten kent.
- Geef elke methode één duidelijke taak
Java-methoden: uitleg
1Schrijf je eigen methoden en roep die aan
Een programma wordt gemakkelijker te volgen als betekenisvolle stappen een naam hebben. Een methode geeft een groep instructies één naam en een aanroep voert die instructies uit op de plaats waar ze nodig zijn. Begin met een methode die steeds dezelfde regel afdrukt en voeg daarna parameters toe, zodat één definitie verschillende invoer kan verwerken. Door een methodekop te lezen en die te koppelen aan een aanroep, zie je welke informatie elke stap nodig heeft voordat je de methodebody bekijkt.
1.1 Definieer een methode en roep die aan
Een methode is een benoemd blok instructies dat een taak uitvoert. Door een methode te definiëren maak je die taak beschikbaar; door haar aan te roepen laat je de taak uitvoeren.
Lees de methodekop en methodebody
public static void printLine() {
System.out.println("----------");
}
De eerste regel is de methodekop. Lees de onderdelen van links naar rechts:
publicstaat toe dat code in andere klassen de methode aanroept.staticzorgt ervoor dat de methode bij de klasse hoort. Er is geen object nodig om haar aan te roepen.voidgeeft aan dat de methode geen waarde teruggeeft.printLinegeeft de taak een naam.()is de lege parameterlijst: deze methode heeft geen invoer nodig.
De accolades omsluiten de methodebody, de instructies die bij een aanroep worden uitgevoerd. Tussen deze methodekop en de openingsaccolade staat geen puntkomma.
Zet de definitie in de klasse
public class Main {
public static void main(String[] args) {
System.out.println("Start");
printLine();
System.out.println("Middle");
printLine();
}
public static void printLine() {
System.out.println("----------");
}
}
main en printLine zijn afzonderlijke methoden binnen Main. De sluitaccolade van main staat vóór de definitie van printLine. Je kunt een methode niet binnen een andere methode definiëren; een verkeerd geplaatste accolade kan “illegal start of expression” opleveren.
De definities mogen in beide volgorden staan. Als je printLine boven main zet, verandert dat niet wanneer de methode wordt uitgevoerd. Een methode die nooit wordt aangeroepen, wordt niet uitgevoerd alleen omdat haar definitie in het bestand staat.
Volg een aanroep en de terugkeer naar de aanroepende code
De aanroep printLine(); bestaat uit de naam, ronde haakjes en een puntkomma, omdat de aanroep op zichzelf een instructie is. De uitvoering begint in main:
- Druk “Start” af.
- Ga naar
printLine, druk tien streepjes af en ga dan verder na de aanroep. - Druk “Middle” af.
- Ga opnieuw naar
printLineen druk opnieuw tien streepjes af.
De uitvoer is:
Start
----------
Middle
----------
Beide aanroepen gebruiken dezelfde definitie. Als je de afgedrukte regel daarin wijzigt, verandert die op beide plaatsen waar de methode wordt gebruikt.
Geef methoden een duidelijke naam en roep ze nauwkeurig aan
Gebruik een werkwoord of werkwoordgroep in camelCase, beginnend met een kleine letter: printReceipt, calculateAverage of isValidCode. Java maakt onderscheid tussen hoofdletters en kleine letters: PrintLine() kan geen methode met de naam printLine vinden. Ook printLine; schrijven mislukt; de ronde haakjes maken deel uit van de aanroep.
Schrijf voor een statische methode in een andere klasse eerst de klassenaam. Math.max(3, 8) geeft 8, Math.abs(-4) geeft 4 en Math.sqrt(16.0) geeft 4.0. Je eigen methoden in dezelfde klasse kun je alleen met hun naam aanroepen.
Deze voorbeelden gebruiken de klassieke vorm met een klasse en public static void main(String[] args). Java 25 ondersteunt ook compacte bronbestanden met void main() en zonder omringende klasse. Gebruik bij het uitvoeren van deze voorbeelden de klassieke vorm; de hulpmethoden zijn gedeclareerd met static. Methoden zoals System.out.println die je uit de Java-bibliotheek aanroept, hoeven zelf niet statisch te zijn.
Belangrijkste punten
- Plaats methodedefinities binnen de klasse en buiten andere methoden.
- Een definitie maakt een taak beschikbaar; een aanroep voert die uit en gaat daarna verder in de aanroepende code.
- Schrijf ronde haakjes bij een aanroep en een puntkomma als de aanroep een instructie is.
- Gebruik een beschrijvende naam in camelCase en neem hoofdletters en kleine letters precies over.
- Roep een statische methode uit een andere klasse aan met de klassenaam, zoals
Math.max(3, 8).
1.2 Geef informatie door aan een methode via parameters
Met een parameter kan één methode waarden verwerken die per aanroep veranderen. Een argument is de waarde die bij de aanroep voor die parameter wordt opgegeven.
Geef elke invoer een type en een naam
public static void printStars(int count) {
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
int count declareert één parameter. In printStars(3); wordt het argument 3 de beginwaarde van count. De lus wordt drie keer uitgevoerd en drukt dus *** af, waarna println() de regel beëindigt. printStars(8); gebruikt dezelfde methodebody met count gelijk aan 8.
Het type schrijf je in de definitie, niet in de aanroep. Schrijf printStars(5);, niet printStars(int 5);.
Bereken argumenten voordat je de methodebody binnengaat
Een argument kan een literal, een variabele of een expressie zijn:
int n = 4;
printStars(n * 2);
Java berekent eerst n * 2. Het geeft de resulterende waarde 8 door, dus de methodebody begint met count gelijk aan 8. De naam van de variabele in de aanroepende code hoeft niet overeen te komen met de naam van de parameter.
Koppel meerdere parameters op positie
Elke parameter heeft een eigen type nodig. Een methode voor een rechthoek kan met deze methodekop beginnen:
public static void printRectangle(int width, int height)
De aanroep printRectangle(5, 2); geeft width de waarde 5 en height de waarde 2. Als je de argumenten omdraait, krijg je een rechthoek die 2 breed en 5 hoog is. Beide aanroepen compileren omdat beide argumenten ints zijn; alleen de bedoelde vorm vertelt je welke volgorde juist is. Als je (int width, height) in de methodekop schrijft, mislukt dat omdat voor height geen type is gedeclareerd.
Bij verschillende typen zijn sommige volgordefouten gemakkelijker te vinden:
public static void printRepeated(String text, int times) {
for (int i = 0; i < times; i++) {
System.out.print(text);
}
System.out.println();
}
printRepeated("ab", 3); drukt “ababab” af. printRepeated(3, "ab"); kan niet worden gekoppeld aan een String gevolgd door een int. Ook het aantal argumenten moet kloppen: bij printRectangle(5); krijgt één parameter geen waarde.
Controleer of numerieke typen passen
Java zet een int automatisch om naar een double met een verbredende typeconversie. Een methode met parameters (double km, double hours) accepteert de argumenten (150, 2) en krijgt daarmee 150.0 en 2.0. Elke int-waarde kan exact als double worden weergegeven.
Java zet een double-argument niet automatisch met een versmallende typeconversie om naar een int-parameter. printStars(2.9); mislukt omdat bij de omzetting het deel achter de komma verloren zou gaan. De expliciete typeconversie in printStars((int) 2.9); levert 2 op, zodat twee sterren worden afgedrukt. Gebruik zo’n typeconversie alleen als het de bedoeling is dat dat deel wordt afgekapt.
Kies een parameter voor elk gegeven dat de taak nodig heeft. Doordat printRepeated tekst en een aantal ontvangt, kun je de methode gebruiken met toetsenbordinvoer, een vaste testaanroep of een andere methode. De methodebody hoeft niet te bepalen waar die waarden vandaan komen.
Belangrijkste punten
- Een parameter wordt in een methodekop gedeclareerd; een argument levert de waarde bij een aanroep.
- Java berekent argumentexpressies voordat de aangeroepen methode wordt uitgevoerd.
- Argumenten passen bij parameters op basis van positie, aantal en een passend type.
- Schrijf voor elke parameter een type, maar schrijf geen typen in de aanroep.
- Een int kan met een verbredende typeconversie een double worden; een double heeft een expliciete typeconversie nodig om een int te worden.
- Als je argumenten van hetzelfde type verwisselt, kan de code compileren en toch een ander resultaat opleveren.
2Laat methoden resultaten teruggeven
Een methode kan meer dan afdrukken: ze kan een waarde teruggeven aan de code die haar aanriep. Daardoor kun je een berekening gebruiken in een andere berekening, een voorwaarde of een later rapport. Volg hoe retourtypen, expressies en toewijzingen samenhangen en gebruik vervolgens return-instructies binnen beslissingen en zoekacties. De plaats van een return is belangrijk: die bepaalt zowel welk antwoord de aanroepende code bereikt als hoeveel van de methode kan worden uitgevoerd.
2.1 Geef een waarde terug en gebruik die
Een retourwaarde is een resultaat dat een methode naar de aanroepende code stuurt. Zodra een aanroep klaar is, kan die worden gebruikt als een expressie met het type van dat resultaat.
Declareer wat wordt teruggegeven
public static int sum(int a, int b) {
return a + b;
}
int vervangt void in de methodekop omdat deze methode een geheel getal teruggeeft. De return-instructie berekent a + b en stuurt de waarde naar de plaats van de aanroep. Voor sum(4, 7) is die waarde 11.
De aanroepende code bepaalt wat er daarna gebeurt:
int total = sum(4, 7);
System.out.println(sum(4, 7));
int doubled = sum(2, 3) * 2;
De eerste regel slaat 11 op; de tweede drukt 11 af; de derde slaat 10 op. Een retourwaarde kun je ook in een voorwaarde gebruiken, zoals if (sum(a, b) > 10).
Een passend int-resultaat kan met een verbredende typeconversie worden omgezet wanneer het uit een double-methode wordt teruggegeven. Een double-resultaat kan niet zonder een geschikte expliciete typeconversie uit een int-methode worden teruggegeven.
Bereken de expressie voordat je het resultaat omzet
public static double average(int a, int b) {
return (a + b) / 2.0;
}
Voor average(3, 4) is de teller 7. Delen door de double-literal 2.0 geeft 3.5. Als de expressie (a + b) / 2 was, zou Java eerst twee ints delen en 3 krijgen. Pas daarna zou Java die waarde met een verbredende typeconversie omzetten naar de teruggegeven waarde 3.0. Een retourtype double herstelt geen geheeltallige deling die al binnen de methodebody is uitgevoerd.
Houd teruggeven en afdrukken gescheiden
| Gedrag van de methode | Wat de aanroepende code ontvangt | Wat op het scherm verschijnt |
|---|---|---|
return a + b; in een int-methode | De som | Niets door deze instructie |
System.out.println(a + b); in een void-methode | Geen waarde | De som |
Een void-aanroep kan geen waarde leveren voor een toewijzing of een andere aanroep. Als printSum void is, mislukt int total = printSum(1, 2); ook al drukt printSum een getal af. Gebruik voor berekeningen een methode die een waarde teruggeeft en laat de aanroepende code kiezen of die wordt afgedrukt.
Geef tekst en ja-neeresultaten terug
Retourtypen omvatten ook String en boolean. Een begroetingsmethode kan "Hello, " + name + "!" teruggeven, wat “Hello, Ana!” oplevert voor het argument "Ana". Een methode isEven(int n) kan n % 2 == 0 teruggeven.
Een opmaakmethode zet een getal om in herbruikbare tekst:
public static String formatDuration(int minutes) {
return minutes / 60 + " h " + minutes % 60 + " min";
}
Voor 135 geeft geheeltallige deling 2 hele uren en geeft de rest 15 minuten. Het resultaat is “2 h 15 min”; voor 60 is het “1 h 0 min”.
Bewaar of combineer het resultaat
Een aanroep zoals sum(4, 7); compileert, maar gooit het resultaat weg. Als square(x) een nieuwe waarde teruggeeft, gebruik dan x = square(x); om die in x op te slaan.
Een resultaat kan ook direct een argument worden. In Math.max(sum(1, 2), 4) geeft sum(1, 2) eerst 3, waarna Math.max(3, 4) de waarde 4 geeft. Bereken de binnenste aanroep voordat je het resultaat in de buitenste gebruikt.
Belangrijkste punten
- Het gedeclareerde retourtype vertelt de aanroepende code wat voor resultaat de aanroep oplevert.
- Teruggeven levert een waarde; afdrukken toont een waarde.
- De expressie wordt berekend voordat het resultaat naar het retourtype wordt omgezet.
- Sla een retourwaarde op als latere code die nodig heeft; een afzonderlijke aanroep gooit de waarde weg.
- Een retourwaarde kan een argument voor een andere methode zijn.
2.2 Gebruik return binnen voorwaardelijke instructies en lussen
Een return-instructie beëindigt de huidige methodeaanroep onmiddellijk. Ook binnen een voorwaarde of een lus verlaat je daarmee de hele methode, niet alleen dat blok.
Geef elk pad een antwoord
public static int larger(int a, int b) {
if (a > b) {
return a;
}
return b;
}
larger(9, 4) geeft 9 terug vanuit de if-instructie. Bij larger(2, 6) wordt de if-body overgeslagen en geeft de laatste return 6 terug. Gelijke invoer zoals (5, 5) bereikt ook de laatste return en levert 5 op. Na de eerste return is geen else nodig, omdat dat pad de methode al heeft verlaten.
In een gewone methode die een waarde teruggeeft, mag geen enkel mogelijk pad de sluitaccolade bereiken zonder een waarde te leveren. Een methode voor het teken van een getal die alleen bij positieve en negatieve invoer een waarde teruggeeft, laat nul zonder antwoord:
public static String sign(int n) {
if (n > 0) {
return "positive";
} else if (n < 0) {
return "negative";
}
return "zero";
}
De laatste return maakt de methode compleet. Twee afzonderlijke if-instructies, één die n > 0 test en één die n <= 0 test, hebben nog steeds een laatste return of een duidelijke if/else-structuur nodig. De returncontrole van Java leidt niet af dat die twee vergelijkingen alle gehele getallen dekken. Een instructie direct na een onvoorwaardelijke return in hetzelfde blok is onbereikbaar en wordt afgewezen.
Beëindig een zoekactie op het juiste moment
public static int firstMultipleOf7(int start, int end) {
for (int i = start; i <= end; i++) {
if (i % 7 == 0) {
return i;
}
}
return -1;
}
Voor (10, 20) wijst de lus 10, 11, 12 en 13 af en geeft daarna 14 terug. De aanroep eindigt zonder 15 tot en met 20 te controleren. Voor (15, 20) eindigt de lus zonder overeenkomst, dus geeft de return erna -1 terug, het afgesproken signaal voor “niet gevonden”.
Als je else { return -1; } binnen de lus zet, stopt de methode na de eerste kandidaat die niet voldoet. De zoekactie vanaf 10 zou dan melden dat niets is gevonden voordat 14 wordt bereikt. De return voor een mislukte zoekactie hoort na het uitproberen van alle kandidaten.
Geef de voorwaarde zelf terug
Een vergelijking levert al een boolean op. Schrijf return n % 2 == 0; in plaats van een if/else die afzonderlijk true en false teruggeeft. De naam van een booleaanse methode begint vaak met is of has, zodat een aanroep binnen een if-instructie natuurlijk leest.
public static boolean isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0)
|| year % 400 == 0;
}
Dit geeft true terug voor 2024 en 2000, maar false voor 1900 en 2023. Gebruik if (isLeapYear(y)) rechtstreeks.
Verlaat een void-methode voortijdig
Een void-methode gebruikt return; zonder waarde. Zo kan printSquareRoot(double x) bij negatieve invoer “No real square root” afdrukken en onmiddellijk terugkeren. Voor andere invoer kan de methode Math.sqrt(x) afdrukken, wat 1.5 oplevert voor 2.25. return 5; schrijven in een void-methode mislukt omdat de methodekop belooft geen waarde terug te geven.
Belangrijkste punten
returnbeëindigt de huidige aanroep onmiddellijk, ook binnen een lus.- Een methode die een waarde teruggeeft, mag haar sluitaccolade niet zonder antwoord bereiken.
- Zet de return voor een mislukte zoekactie na de lus, zodat latere kandidaten kunnen worden gecontroleerd.
- Een vergelijking kun je rechtstreeks als boolean teruggeven.
- Gebruik
return;zonder waarde om een void-methode voortijdig te verlaten. - Code direct na een onvoorwaardelijke return in hetzelfde blok is onbereikbaar.
3Volg variabelen en aanroepen tijdens de uitvoering van een programma
Een methodeaanroep geeft een hulpmethode geen toegang tot elke variabele in het programma. Elke aanroep heeft zijn eigen parameters en lokale variabelen en Java bewaart die waarden in een afzonderlijk stackframe. Gebruik het bereik om te bepalen waar een naam is toegestaan, waardeoverdracht om te voorspellen wat toewijzingen kunnen veranderen en de aanroepstack om onafgemaakt werk te volgen. Deze drie begrippen verklaren waarom twee variabelen dezelfde naam kunnen hebben terwijl ze verschillende waarden bevatten.
3.1 Bepaal waar je elke variabele kunt gebruiken
Het bereik van een variabele is het deel van de code waar haar naam kan worden gebruikt. Begin bij de accolades rond de declaratie: een lokale naam hoort bij een bepaalde methode of een bepaald blok.
Lokale variabelen van de aanroepende methode blijven daar
public static void main(String[] args) {
int price = 20;
printDouble(price);
}
public static void printDouble(int price) {
System.out.println(price * 2);
}
De price in main en de parameter price in printDouble zijn afzonderlijke variabelen. Het argument levert de waarde die de hulpmethode nodig heeft, zodat de hulpmethode 40 afdrukt.
Als je de parameter verwijdert en printDouble() aanroept, kan de hulpmethode de lokale variabele price van main niet lezen. De methodebody zou mislukken met “cannot find symbol”. Als je de ene methode vanuit de andere aanroept, worden hun bereiken niet samengevoegd. Verschillende methoden mogen elk de naam count gebruiken zonder hun variabelen aan elkaar te koppelen.
Een genest blok maakt een kleiner bereik
Een lokale variabele kan worden gebruikt vanaf haar declaratie tot en met de sluitaccolade van haar blok. Een parameter is beschikbaar in de hele methodebody. Een teller die in for (int i = 0; i < 3; i++) is gedeclareerd, hoort bij die lus; i kan daarna niet meer worden gelezen.
Om een resultaat na een lus te bewaren, declareer je het vóór de lus:
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
}
System.out.println(sum);
Door het optellen krijgt sum achtereenvolgens de waarden 1, 3, 6, 10 en 15. De laatste afdrukinstructie kan sum lezen omdat het omringende blok nog niet is geëindigd. i is alleen nodig voor de lus en blijft binnen het bereik daarvan.
Als je int sum = 0; naar de lusbody verplaatst, ontstaat bij elke herhaling een nieuwe sum. Elke variabele begint bij nul en verdwijnt aan het einde van die herhaling. De variabele kan geen lopend totaal bijhouden en kan na de lus niet worden afgedrukt.
Controleer namen en beginwaarden afzonderlijk
Twee lokale variabelen met dezelfde naam kunnen binnen één methode geen overlappend bereik hebben. Een methode met een parameter x kan niet nog een lokale variabele x declareren; een lus die i declareert, kan niet nog een i in haar body declareren. Geef de tweede variabele een andere naam of gebruik de bestaande.
Twee opeenvolgende lussen mogen elk int i declareren. Het bereik van de eerste lus is geëindigd vóór de tweede declaratie. Accolades, niet het hele bestand, bepalen of je de naam opnieuw kunt gebruiken.
Een toegestane naam heeft ook een waarde nodig voordat die wordt gelezen. int total; total++; mislukt omdat ++ de oude waarde moet lezen en een lokale variabele niet automatisch een beginwaarde krijgt. Gebruik int total = 0; voor een lopend totaal.
Houd een lokale variabele in het kleinste blok dat die nodig heeft. Als een methode informatie van de aanroepende code nodig heeft, maak die informatie dan tot een parameter. Als de aanroepende code een resultaat nodig heeft, geef dat dan terug. Zo laten de methodekop en methodebody zien waar de gegevens vandaan komen.
Belangrijkste punten
- Een lokale naam is beschikbaar vanaf de declaratie tot het einde van het blok.
- Een aangeroepen methode kan de lokale variabelen van de aanroepende code niet op naam lezen.
- Declareer een accumulator vóór een lus als die een totaal moet bijhouden of daarna moet worden gelezen.
- Het bereik van lokale namen mag binnen één methode niet overlappen en lokale variabelen hebben vóór gebruik een waarde nodig.
3.2 Begrijp dat argumentwaarden als kopieën worden doorgegeven
Java geeft argumenten op waarde door. Aan het begin van een aanroep ontvangt elke parameter een kopie van de waarde van het argument. Een toewijzing aan de parameter verandert die lokale variabele.
Volg de kopie afzonderlijk
public static void main(String[] args) {
int score = 10;
addBonus(score);
System.out.println(score);
}
public static void addBonus(int score) {
score = score + 5;
System.out.println(score);
}
Er zijn twee variabelen met de naam score. Volg hun waarden op elk moment:
| Moment | score van main | score van addBonus |
|---|---|---|
| Vóór de aanroep | 10 | Nog geen aanroep |
Bij het binnengaan van addBonus | 10 | 10 |
| Na de toewijzing in de hulpmethode | 10 | 15 |
| Nadat de hulpmethode is teruggekeerd | 10 | Aanroep is beëindigd |
De hulpmethode drukt 15 af, daarna drukt main 10 af. Een gedeelde naam betekent niet dat de twee variabelen dezelfde opslagruimte delen. Als je de parameter een andere naam geeft, verandert dit gedrag niet.
Geef de nieuwe waarde terug en sla die op
public static int addBonus(int score) {
return score + 5;
}
Schrijf bij deze versie score = addBonus(score);. Java kopieert de oude waarde naar de parameter, berekent 15, geeft die waarde terug en wijst die toe aan de variabele van de aanroepende code. De toewijzing in de aanroepende code is de stap die die variabele verandert.
Een resultaat kan ook ergens anders worden opgeslagen. Als triple(int n) zijn lokale variabele n met 3 vermenigvuldigt en die teruggeeft, blijft na int a = 4; int b = triple(a); de waarde van a gelijk aan 4 en krijgt b de waarde 12. Als je a + " " + b afdrukt, verschijnt “4 12”.
Pas dezelfde regel toe op String-referenties
Een String-variabele bevat een referentie naar een String-object. Java kopieert die referentie naar een String-parameter:
public static void exclaim(String text) {
text = text + "!";
}
Als word in de aanroepende code naar “hi” verwijst, blijft word na exclaim(word); naar “hi” verwijzen. Concatenatie maakt een nieuwe String en de toewijzing verandert alleen waarnaar de parameter verwijst. De bestaande inhoud van strings kan niet worden gewijzigd.
Om de nieuwe tekst te bewaren, geef je text + "!" terug vanuit een String-methode zoals exclaimed en schrijf je daarna word = exclaimed(word);.
Bij veranderlijke objecten, zoals lijsten, kan een gekopieerde referentie nog steeds naar hetzelfde object wijzen. Een methode kan via de gekopieerde referentie de inhoud van dat object wijzigen. Door de parameter een nieuwe waarde te geven, kan de variabele van de aanroepende code nog steeds niet naar een ander object gaan verwijzen. Zowel de regel voor gekopieerde referenties als die voor gekopieerde getallen valt onder waardeoverdracht.
Je mag een parameter een nieuwe waarde geven, maar een afzonderlijke lokale variabele zoals result kan een langere berekening gemakkelijker leesbaar maken: de oorspronkelijke invoer blijft beschikbaar en je ziet welke waarde wordt teruggegeven.
Belangrijkste punten
- Elke parameter ontvangt een kopie van de waarde van het argument.
- Een parameter een nieuwe waarde geven laat de variabele van de aanroepende code onveranderd.
- Om een berekende vervangende waarde te bewaren, geef je die terug en wijs je die toe in de aanroepende code.
- Een gekopieerde objectreferentie kan naar hetzelfde veranderlijke object verwijzen, maar een nieuwe toewijzing aan de parameter blijft lokaal.
3.3 Volg methodeaanroepen op de aanroepstack
De aanroepstack houdt aanroepen bij die zijn begonnen maar nog niet zijn voltooid. Elke aanroep krijgt een stackframe met zijn parameters, lokale variabelen en de plaats waar de aanroepende code verdergaat.
Plaats een frame, voltooi het en verwijder het
De stack werkt volgens laatst erin, eerst eruit. De nieuwste aanroep staat bovenaan en wordt uitgevoerd terwijl de aanroepende code eronder wacht. Wanneer de aanroep terugkeert, verwijdert Java het frame en hervat de aanroepende code.
public static void main(String[] args) {
int total = totalSeconds(2, 30);
System.out.println(total);
}
public static int totalSeconds(int minutes, int seconds) {
int fromMinutes = toSeconds(minutes);
return fromMinutes + seconds;
}
public static int toSeconds(int minutes) {
return minutes * 60;
}
Volg het onafgemaakte werk:
mainstart en roepttotalSeconds(2, 30)aan. De toewijzing aantotalmoet wachten.- Het nieuwe frame heeft
minutes = 2enseconds = 30. Het roepttoSeconds(minutes)aan en wacht opfromMinutes. toSecondskrijgt zijn eigenminutes = 2. De methode geeft120terug en haar frame wordt verwijderd.totalSecondsslaatfromMinutes = 120op, telt30erbij op en geeft150terug. Haar frame wordt verwijderd.mainslaattotal = 150op en drukt150af.
Op het diepste punt zijn de frames van onder naar boven main, totalSeconds en toSeconds. Beide hulpmethoden hebben een parameter met de naam minutes, maar die parameters staan in verschillende frames. De lokale variabelen van de wachtende aanroepende code worden niet zichtbaar voor de methode erboven.
Een latere aanroep krijgt een nieuw frame. Een lokale teller onthoudt zijn vorige waarde niet nadat zijn aanroep is beëindigd; de retourwaarde kan een resultaat teruggeven.
Lees een stacktrace vanaf de fout naar buiten
Bij een niet-afgehandelde exceptie drukt Java een stacktrace af die laat zien waar de fout optrad en welke aanroepen daartoe leidden. Hier is een volledig bestand:
public class Main {
public static void main(String[] args) {
report(300, 0);
}
public static void report(int meters, int minutes) {
int speed = perMinute(meters, minutes);
System.out.println(speed + " m per minute");
}
public static int perMinute(int meters, int minutes) {
return meters / minutes;
}
}
De eerste uitvoerregel is Exception in thread "main" java.lang.ArithmeticException: / by zero. De frames daaronder zijn:
at Main.perMinute(Main.java:12)
at Main.report(Main.java:7)
at Main.main(Main.java:3)
Het bovenste frame toont waar de geheeltallige deling door nul plaatsvindt. De volgende twee geven de plaatsen aan van de aanroepen die daartoe leidden. De regelnummers horen bij precies deze bestandsindeling; als je een regel toevoegt, veranderen ze.
De stack heeft een beperkte ruimte. Een keten die aanroepen blijft toevoegen zonder ze te laten eindigen, kan een StackOverflowError veroorzaken. In de stackweergave van een debugger kun je dezelfde keten bekijken terwijl de uitvoering bij een onderbrekingspunt is gepauzeerd, inclusief de afzonderlijke variabelen van elke wachtende aanroep.
Belangrijkste punten
- Elke aanroep plaatst een nieuw frame op de stack; een return verwijdert dat frame en hervat de aanroepende code.
- De nieuwste onvoltooide aanroep wordt als eerste uitgevoerd: de stack werkt volgens laatst erin, eerst eruit.
- Lokale variabelen met dezelfde naam in verschillende frames zijn afzonderlijke variabelen.
- Volg een retourwaarde terug naar de wachtende expressie of toewijzing.
- Lees een stacktrace van het bovenste frame met de fout naar de aanroepende methoden daaronder.
- Een keten die frames blijft toevoegen, kan de stack uitputten.
4Overlaad methoden
Eén nuttige bewerking kan verschillende soorten invoer accepteren. Door te overladen kunnen die vormen een naam delen, terwijl elke vorm een eigen parameterlijst heeft. Controleer eerst of twee declaraties werkelijk verschillende signaturen hebben. Volg daarna de keuze van de compiler bij een aanroep: tel de argumenten, bepaal hun typen en vergelijk de passende versies. Het type van een ontvangende variabele kan een aanroep niet redden als de argumenten geen geschikte overladen methodevariant aanwijzen.
4.1 Schrijf overladen methoden
Overladen geeft methoden dezelfde naam met verschillende parameterlijsten. Het is nuttig wanneer de methoden dezelfde taak uitvoeren voor verschillende aantallen of typen invoer.
Vergelijk signaturen
Voor deze methoden bestaat een signatuur uit de naam en de geordende parametertypen. Het aantal parameters volgt uit die lijst.
public static int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
public static int max(int a, int b, int c) {
return max(max(a, b), c);
}
public static double max(double a, double b) {
if (a > b) {
return a;
}
return b;
}
De signaturen zijn max(int, int), max(int, int, int) en max(double, double). max(3, 9) gebruikt de eerste en geeft 9 terug. max(3, 9, 5) roept de tweede aan: de binnenste aanroep met twee ints geeft 9 terug, waarna de buitenste aanroep met twee ints 9 en 5 vergelijkt en ook 9 teruggeeft. max(2.5, 1.0) gebruikt de double-versie en geeft 2.5 terug.
Weet welke wijzigingen niet meetellen
Als je alleen een retourtype verandert, ontstaat geen overladen methodevariant. Deze methodekoppen zijn met elkaar in conflict:
public static int area(int w, int h)
public static double area(int w, int h)
Beide hebben de signatuur area(int, int). Java wijst de dubbele declaratie af. Ook als je de parameters hernoemt naar width en height, blijft de signatuur gelijk: de aanroepende code geeft waarden door op positie, niet op parameternaam.
De volgorde van verschillende typen telt wel mee. describe(String s, int n) en describe(int n, String s) zijn verschillende signaturen. Ze compileren samen, maar je moet bij een aanroep een gemakkelijk te verwarren volgorde onthouden, dus gebruik zo’n paar alleen als het het ontwerp helpt.
Laat een kortere methodevariant een standaardwaarde leveren
Java biedt geen standaardwaarden voor parameters in methodedeclaraties. Een kortere overladen methodevariant kan een langere aanroepen met een vast argument:
public static void printLine(int length, char symbol) {
for (int i = 0; i < length; i++) {
System.out.print(symbol);
}
System.out.println();
}
public static void printLine(int length) {
printLine(length, '-');
}
printLine(5, '*'); drukt ***** af. printLine(4); gaat naar de kortere methode, die de langere aanroept met 4 en '-', en drukt ---- af. De lus staat op één plaats, dus wijzigingen in de afdruktaak gelden voor beide vormen.
De Java-bibliotheek gebruikt ook overladen methodevarianten. System.out.println accepteert een int, een double, een char, een boolean of een String via verschillende versies. Math.abs en Math.max bieden versies voor int, long, float en double.
Geef de gedeelde naam één betekenis. Een bon afdrukken en een etiket afdrukken zijn verschillende taken; duidelijke namen zoals printReceipt en printLabel vertellen de aanroepende code welke taak wordt uitgevoerd.
Belangrijkste punten
- Overladen methodevarianten delen een naam en verschillen in het aantal, de typen of de volgorde van parametertypen.
- Retourtypen en parameternamen maken geen onderscheid tussen signaturen.
- Een kortere overladen methodevariant kan een langere aanroepen met een vast standaardargument.
- Gebruik één overladen naam voor één taak met verschillende vormen van invoer.
4.2 Voorspel welke overladen methode wordt uitgevoerd
De compiler kiest een overladen methodevariant op basis van het aantal en de typen argumenten. Bepaal die keuze voordat je kijkt hoe de retourwaarde wordt gebruikt.
Begin met exacte overeenkomsten
Stel dat een klasse show(int x) en show(double x) definieert. show(5) gebruikt de int-versie omdat de literal 5 een int is. show(5.0) gebruikt de double-versie. Een geheelgetalswaarde die als 5.0 is geschreven, is nog steeds een double-expressie.
Vergelijk bij een aanroep met meerdere argumenten het type op elke positie. Een mogelijke methodevariant met het verkeerde aantal argumenten kan niet passen.
Sta zo nodig verbredende typeconversie toe
Als alleen show(double x) bestaat, is show(5) geldig: de int wordt met een verbredende typeconversie omgezet naar 5.0. De mogelijke verbredende typeconversies voor primitieve typen omvatten:
byte → short → int → long → float → double
char → int → long → float → double
Als zowel show(long x) als show(double x) bestaat, kiest een int-argument voor long. Dat is het specifiekere passende parametertype: een long kan met een verbredende typeconversie naar double worden omgezet, terwijl een double niet op die manier terug kan naar long.
Een verbredende typeconversie is een toegestane numerieke omzetting; dat betekent niet dat bij elke omzetting elk cijfer behouden blijft. Met name kan de omzetting van een voldoende grote long naar double de waarde afronden. De omzetting van int naar double in de eerdere voorbeelden behoudt alle int-waarden exact.
Een char heeft ook een numerieke waarde. Bij letter(int code) en letter(String text) roept letter('A') de int-versie aan met 65. Een teken wordt geen String om bij een parameter te passen. Dubbele aanhalingstekens in "A" zouden er daarentegen een String-argument van maken.
Wijs automatische versmallende typeconversie af
Met alleen show(int x) mislukt show(5.0). Java zet een double-argument niet met een versmallende typeconversie om alleen omdat de waarde toevallig een geheel getal is. show((int) 5.0) geeft na een expliciete typeconversie een int door.
Evenzo kunnen versies van max voor twee en drie ints max(1) niet accepteren. Geen enkele mogelijke methodevariant heeft het vereiste aantal parameters, dus meldt de compiler “no suitable method found”. Vergelijk de lijst met mogelijke methoden met de opgegeven argumenten.
Houd de selectie van de overladen methodevariant gescheiden van de omzetting van het resultaat
Bekijk int twice(int n) en double twice(double x). In double d = twice(3); kiest het argument de int-versie. Die aanroep geeft 6 terug, waarna de toewijzing die met een verbredende typeconversie omzet naar 6.0. De doelvariabele d kiest niet de double-versie.
Herken een dubbelzinnige aanroep
public static void combine(int a, double b) { }
public static void combine(double a, int b) { }
combine(1, 2) past bij de eerste na een verbredende typeconversie van het tweede argument en bij de tweede na zo’n conversie van het eerste. Geen van beide signaturen is over beide posities genomen specifieker. Java meldt “reference to combine is ambiguous”; het kiest niet de definitie die als eerste is geschreven.
combine(1, 2.0) past alleen bij (int, double), omdat de andere signatuur een versmallende typeconversie van 2.0 nodig zou hebben. Een duidelijk argumenttype of een betere verzameling overladen methodevarianten neemt de dubbelzinnigheid weg.
Belangrijkste punten
- Kies tijdens het compileren een overladen methodevariant op basis van het aantal en de typen argumenten.
- Een exacte overeenkomst krijgt voorrang; een verbredende typeconversie kan een andere versie passend maken.
- Java voert geen automatische versmallende typeconversie uit op numerieke methodeargumenten.
- De variabele die het resultaat ontvangt, kiest de overladen methodevariant niet.
- Dubbelzinnigheid betekent dat meerdere versies passen en geen daarvan voor de hele aanroep specifieker is.
5Verdeel een programma in methoden
De methoden van een programma moeten het plan ervan zichtbaar maken. Geef elke methode één betekenisvolle taak, geef haar de waarden die ze nodig heeft en gebruik haar resultaat voor de volgende stap. Herhaalde code wijst vaak op een ontbrekende methode; een lange methode wijst vaak op meerdere taken die door elkaar lopen. Plan eerst de methodekoppen, bouw kleine onderdelen met bekende resultaten en verbind die geleidelijk met elkaar. Daardoor worden zowel de gegevensstroom als de plaats van een nieuwe fout gemakkelijker zichtbaar.
5.1 Geef elke methode één duidelijke taak
Decompositie betekent dat je een probleem in kleinere taken verdeelt en elke taak in een eigen methode oplost. Kies taken waarvan de namen iemand helpen het plan van het programma te lezen.
Houd berekeningen gescheiden van invoer en uitvoer
Een programma over een fietstocht heeft een snelheidsberekening en een rapport nodig. Die gebruiken dezelfde gegevens, maar hebben verschillende taken:
public static double kilometersPerHour(double km, double hours) {
return km / hours;
}
public static void printRideReport(double speed) {
System.out.println("Speed: " + speed + " km/h");
}
Voor een tocht van 150 km in 2 uur geeft de berekening 75.0 terug. De rapportagemethode ontvangt die waarde en geeft die weer. Aanroepende code verbindt de stappen:
double speed = kilometersPerHour(150, 2);
printRideReport(speed);
De berekening leest geen toetsenbordinvoer en drukt geen rapport af. Een ander programma kan de methode gebruiken om fietstochten te vergelijken of snelheden op te slaan zonder haar methodebody te wijzigen. Om de methode te testen, roep je haar aan met bekende invoer en vergelijk je het teruggegeven getal met het verwachte getal.
Herken een methode met te veel taken
Een naam zoals readAndCheckAndPrint wijst op meerdere handelingen. Andere aanwijzingen zijn onderdelen die door commentaar worden afgebakend, een methodebody die langer is dan één scherm en groepen variabelen die doelen dienen die niets met elkaar te maken hebben. Dit zijn redenen om de methode te bekijken, geen mechanische grenzen aan het toegestane aantal regels.
Splits op een betekenisvolle grens. Invoercode kan een waarde ophalen, een booleaanse hulpmethode kan die controleren, een berekening kan een resultaat teruggeven en een rapportagemethode kan dat resultaat weergeven. Dan leest main als een kort verslag van hoe die taken samenhangen.
Gerichte methoden kun je gemakkelijker afzonderlijk lezen, hergebruiken en testen. Als een rapportagevorm verandert, pas je de rapportagemethode aan. Als een berekening fout is, test je die berekening zonder een hele reeks invoer te hoeven typen.
Laat de methodekop de gegevensstroom uitleggen
In kilometersPerHour(double km, double hours) geeft de naam het resultaat aan, geven de parameternamen de grootheden aan en geeft het retourtype double aan om wat voor antwoord het gaat. Een kort Javadoc-commentaar kan de betekenis van de invoer en het resultaat toevoegen:
/**
* Calculates a ride's average speed.
* @param km distance in kilometers
* @param hours elapsed time in hours, greater than zero
* @return speed in kilometers per hour
*/
Plaats dat commentaar direct boven de methodekop. Nuttig commentaar voegt informatie toe, zoals eenheden of een eis aan de invoer; het hoeft niet elke regel van de methodebody te beschrijven.
Een hulpmethode die alleen binnen haar eigen klasse nodig is, kan private static zijn. private voorkomt dat andere klassen de methode aanroepen, terwijl code in dezelfde klasse haar nog wel kan gebruiken. Met public static is de hulpmethode beschikbaar voor andere klassen.
Als je elke vanzelfsprekende instructie in een eigen methode onderbrengt, kan ook dat het plan onduidelijk maken. Behoud een methode wanneer haar naam voor een betekenisvolle stap of herbruikbare berekening staat. Een keten van hulpmethoden die alleen dezelfde aanroep doorgeven, voegt plaatsen toe die je moet bekijken zonder meer van de taak uit te leggen.
Belangrijkste punten
- Verdeel een programma in betekenisvolle taken met duidelijke namen.
- Berekeningsmethoden ontvangen parameters en geven resultaten terug; rapportagemethoden geven die weer.
- Gerichte hulpmethoden kun je afzonderlijk hergebruiken en testen.
- Een methodekop en een kort Javadoc-commentaar kunnen invoer, eenheden en resultaat beschrijven.
- Gebruik
private staticvoor hulpmethoden die alleen hun eigen klasse mag aanroepen. - Splits waar een naam de taak verduidelijkt, niet bij elke afzonderlijke instructie.
5.2 Vervang herhaalde code door een methode met parameters
Dubbele code herhaalt dezelfde taak op meerdere plaatsen. Als alleen de invoerwaarden verschillen, kan één methode met parameters het gemeenschappelijke werk bij elkaar houden.
Zoek de gemeenschappelijke berekening
Stel dat een programma de getallen van 1 tot en met 10 optelt en daarna die van 1 tot en met 50:
int total1 = 0;
for (int i = 1; i <= 10; i++) {
total1 += i;
}
System.out.println("Sum 1 to 10: " + total1);
int total2 = 0;
for (int i = 1; i <= 50; i++) {
total2 += i;
}
System.out.println("Sum 1 to 50: " + total2);
Beide lussen beginnen bij 1, tellen op bij een totaal en stoppen bij een bovengrens. Alleen die grens verandert. Een parameter n kan die doorgeven aan een gemeenschappelijke berekening.
Breng de code onder in een methode
public static int sumUpTo(int n) {
int total = 0;
for (int i = 1; i <= n; i++) {
total += i;
}
return total;
}
n is de wisselende invoer. total en i zijn werkvariabelen die binnen de hulpmethode horen. De aanroepende code heeft de uiteindelijke som nodig, dus geeft de hulpmethode een int terug.
Vervang beide herhaalde delen:
System.out.println("Sum 1 to 10: " + sumUpTo(10));
System.out.println("Sum 1 to 50: " + sumUpTo(50));
sumUpTo(10) geeft 55 terug en sumUpTo(50) geeft 1275 terug. De afgedrukte regels zijn “Sum 1 to 10: 55” en “Sum 1 to 50: 1275”, net als voorheen. De beschrijvingen blijven in de aanroepende code; de lus voert alleen de berekening uit.
Controleer de methode-extractie in een vaste volgorde
- Markeer de instructies die de herhaalde taak uitvoeren.
- Bepaal elke waarde die tussen de kopieën verschilt.
- Maak van die waarden parameters met passende typen en geef elk resultaat terug dat buiten de methode nodig is.
- Vervang elke kopie door een aanroep met de oorspronkelijke invoer.
- Voer het programma vóór en na de wijziging uit met dezelfde invoer en vergelijk het gedrag.
De structuur van code wijzigen terwijl het gedrag behouden blijft, heet refactoring. Als je één oorspronkelijke kopie laat staan, moet je bij een latere correctie nog steeds twee plaatsen aanpassen. Een afdrukinstructie naar een lus verplaatsen of een eindpunt van een lus veranderen, wijzigt het gedrag, ook als de code nu korter is.
Als twee verschillen verschillende typen hebben, gebruik je passende parameters. Verschillende teksten een verschillend aantal keren herhalen wijst op printRepeated(String text, int times); het woord is een String en het aantal is een int.
Code die op elkaar lijkt, voert niet altijd dezelfde taak uit. Een booleanparameter die een methode tussen verschillende berekeningen laat schakelen, kan haar aanroepen moeilijk te begrijpen maken. Geef verschillende taken verschillende namen. Breng de herhaalde bewerking alleen onder in een methode als die bij wisselende invoer één duidelijke betekenis behoudt.
Belangrijkste punten
- Bepaal de gemeenschappelijke taak en maak van de wisselende invoer parameters.
- Houd werkvariabelen lokaal en geef elk resultaat terug dat de aanroepende code nodig heeft.
- Pas refactoring toe op elke kopie en vergelijk het gedrag met dezelfde invoer.
- Voeg kopieën van dezelfde taak samen, geen verschillende taken die alleen op elkaar lijken.
5.3 Ontwerp een programma top-down en test het methode voor methode
Top-downontwerp begint met de hele taak en verfijnt die tot kleinere methodeaanroepen. Bepaal wat elke aanroep nodig heeft en teruggeeft voordat je elk detail invult.
Plan de stappen en methodekoppen
Een programma voor wekelijkse beweging leest 7 dagelijkse tijdsduren, telt die op en drukt een rapport af. De hulpmethoden kun je als volgt plannen:
readMinutes(Scanner scanner, int day)geeft een geldig aantal minuten voor één dag terug.isValidMinutes(int minutes)geeft aan of de invoer van 0 tot en met 1440 loopt.formatDuration(int minutes)geeft tekst met hele uren en resterende minuten terug.averagePerDay(int total, int days)geeft een gemiddelde als double terug.printSummary(int totalMinutes, int days)drukt het rapport af.
Dezelfde Scanner wordt aan elke invoeraanroep doorgegeven. Een hulpmethode zoals isValidMinutes hoeft niet zelf invoer te lezen.
Gebruik stubs tijdens het bouwen
Een stub heeft de definitieve methodekop, maar een tijdelijke minimale methodebody, zoals return 0;. Daarmee kan het programma compileren voordat een hulpmethode is geïmplementeerd. Vervang één stub, compileer en controleer die methode voordat je de volgende vervangt. Een stub die compileert is nog steeds onaf werk; het vaste antwoord kan een echte berekening niet controleren.
Hier is het voltooide programma:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int total = 0;
for (int day = 1; day <= 7; day++) {
total += readMinutes(scanner, day);
}
printSummary(total, 7);
}
public static int readMinutes(Scanner scanner, int day) {
System.out.println("Minutes for day " + day + ":");
int minutes = scanner.nextInt();
while (!isValidMinutes(minutes)) {
System.out.println("Enter minutes from 0 to 1440:");
minutes = scanner.nextInt();
}
return minutes;
}
public static boolean isValidMinutes(int minutes) {
return minutes >= 0 && minutes <= 1440;
}
public static String formatDuration(int minutes) {
return minutes / 60 + " h " + minutes % 60 + " min";
}
public static double averagePerDay(int total, int days) {
return (double) total / days;
}
public static void printSummary(int totalMinutes, int days) {
System.out.println("Total: " + formatDuration(totalMinutes));
System.out.println("Daily average: "
+ averagePerDay(totalMinutes, days) + " min");
if (totalMinutes >= 150) {
System.out.println("Weekly goal reached");
}
}
}
Bij gehele invoer herhaalt readMinutes de controle van het bereik totdat het getal geldig is. Met de dagelijkse invoer 30, 45, 0, 60, 90, 45 en 45 is het totaal 315. De opmaak levert “5 h 15 min” op, het gemiddelde is 45.0 minuten en het programma meldt dat het weekdoel van 150 minuten is bereikt.
Controleer kleine methoden en hun grenzen
Roep elke berekening aan met bekende resultaten. formatDuration(0) moet “0 h 0 min” opleveren, 59 geeft “0 h 59 min”, 60 geeft “1 h 0 min” en 135 geeft “2 h 15 min”. De invoer net onder en op 60 controleert de overgang van minuten naar een heel uur.
Test voor isValidMinutes de waarden -1, 0, 1440 en 1441. De verwachte resultaten zijn false, true, true en false. Door verwachte en werkelijke waarden naast elkaar af te drukken, maak je een fout zichtbaar. JUnit automatiseert dit soort controles.
Bottom-upontwikkeling begint met het schrijven en testen van kleine hulpmethoden en voegt die daarna samen tot grotere stappen. Je kunt top-down plannen en bottom-up bouwen: bepaal eerst de gegevensstroom, toon aan dat de kleine berekeningen werken en controleer dan het samengevoegde programma.
Belangrijkste punten
- Top-downontwerp zet een hele taak om in aanroepen en verfijnt daarna elke taak.
- Bepaal de invoer en het retourtype van elke hulpmethode vóór de methodebody.
- Een stub behoudt een geplande methodekop terwijl de methodebody nog tijdelijk is.
- Test bekende resultaten en waarden op of rond grenzen.
- Bouw en controleer één methode tegelijk en test daarna het samengevoegde programma.
- Bottom-upontwikkeling bouwt kleine hulpmethoden voordat die worden gecombineerd.
Java-methoden: voorbeelden
1Bouw een herbruikbare methode om lijnen af te drukken
11 stappen
- 1IntroductieMaak van een herhaalde handeling een aanroep
Een rapport heeft op meerdere plaatsen een kort scheidingsteken nodig. Door die handeling een methodenaam te geven, kan het rapport om een scheidingsteken vragen zonder de afdrukinstructies te herhalen. Die benoemde handeling is een methode en één definitie dient voor elke aanroep.
Begin met een vast scheidingsteken. Laat de aanroepende code daarna de breedte en het symbool kiezen met parameters. Volg de definitie, de aanroep en de opgegeven waarden als drie verschillende onderdelen van de taak.
- 2UitlegLees een methodekop
public static void printDivider() { System.out.println("===="); }printDivideris de naam.publicstaat aanroepen vanuit andere klassen toe;staticbetekent dat er geen object nodig is.voidgeeft aan dat er geen waarde terugkomt en()geeft aan dat er geen invoer nodig is.De instructie tussen de accolades is de methodebody. Er wordt niets afgedrukt alleen omdat deze definitie bestaat.
- 3TipZet de hulpmethode naast main
In een klassieke klasse zijn
mainenprintDividerafzonderlijke methoden binnen dezelfde klasseaccolades. Sluit de methodebody vanmainvoordat je met de methodekop van de hulpmethode begint.Een hulpmethode mag boven of onder
mainstaan; haar plaats bepaalt niet wanneer ze wordt uitgevoerd. Een definitie binnenmainwordt afgewezen. Controleer eerst de accolades als een methodekop “illegal start of expression” oplevert. - 4VoorbeeldVolg de eerste aanroep
Stel dat
mainhet volgende bevat:System.out.println("Items"); printDivider(); System.out.println("End");De uitvoering drukt eerst “Items” af. De aanroep gaat naar
printDivider, dat “====” afdrukt. Wanneer de hulpmethode klaar is, gaatmainverder met de volgende instructie en drukt “End” af.De methodebody van de hulpmethode wordt uitgevoerd tussen de twee instructies van de aanroepende code, precies waar de aanroep staat.
- 5UitdagingPlaats een tweede scheidingsteken
mainroeptprintDivider();aan, drukt"A"af en roept opnieuwprintDivider();aan. Welke drie regels verschijnen?---reveal---
De regels zijn “====”, “A” en “====”. Elke aanroep gaat dezelfde methodebody van de hulpmethode in, drukt één keer af en keert terug naar zijn eigen plaats in
main.Met
printDivider;maak je geen aanroep. Ook zonder argumenten zijn de ronde haakjes vereist. - 6UitlegMaak de breedte tot invoer
Vervang de vaste methodebody door een lus:
public static void printDivider(int length) { for (int i = 0; i < length; i++) { System.out.print("="); } System.out.println(); }lengthis een parameter die in de methodekop is gedeclareerd. InprintDivider(6);wordt het argument6de beginwaarde ervan. Zes herhalingen van de lus drukken zes symbolen af voordat de regel eindigt. - 7VoorbeeldBereken een expressie vóór de aanroep
int sections = 3; printDivider(sections + 2);Bereken eerst
sections + 2om5te krijgen. Ga daarna naar de hulpmethode met parameterlength = 5. De lus drukt “=====” af.sectionsenlengthhoeven niet dezelfde naam te hebben. Een parameter ontvangt de berekende argumentwaarde; de aanroepende code zet het type niet in de aanroep. - 8VoorbeeldVoeg een tweede veranderende invoer toe
Gebruik het volgende om ook het symbool te kiezen:
public static void printDivider(int length, char symbol) { for (int i = 0; i < length; i++) { System.out.print(symbol); } System.out.println(); }De aanroep
printDivider(3, '+');geeft3door aanlengthen'+'aansymbolen drukt “+++” af. Elke parameter heeft een eigen type in de methodekop nodig. - 9TipControleer aantal, volgorde en type
Een aanroep moet voor elke parameter een passende waarde leveren. Bij
printDivider(3);ontbreekt nu het symbool, terwijlprintDivider("3", '+');tekst levert waar een int nodig is.Java kan een int met een verbredende typeconversie omzetten naar double voor een double-parameter. Het kan
3.7niet automatisch met een versmallende typeconversie passend maken voor deze int-parameter. De expliciete typeconversie(int) 3.7levert3door het deel achter de komma af te kappen. - 10UitdagingVoorspel een aanroep met parameters
Welke regel drukt dit af met de hulpmethode met twee parameters?
int width = 4; printDivider(width - 1, '#');---reveal---
Het drukt “###” af. De expressie wordt berekend tot
3, daarna ontvangt de eerste parameter dat aantal en de tweede'#'. De lus wordt drie keer uitgevoerd.De aanroep is een instructie en eindigt dus met een puntkomma. De argumentexpressies bevatten waarden, geen parameterdeclaraties.
- 11SamenvattingLees de handeling en haar invoer
Een definitie geeft een taak een methodekop en methodebody; een aanroep voert de taak uit en hervat daarna de aanroepende code. Houd definities binnen de klasse en buiten andere methoden.
Parameters beschrijven de benodigde invoer. Aanroepen leveren berekende argumenten in de passende volgorde, met het juiste aantal en passende typen.
2Geef antwoorden terug en voltooi zoekacties
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieGeef een resultaat terug aan de aanroepende code
- 2UitlegLaat een aanroep voor een waarde staan
- 3KernpuntAfdrukken kan geen waarde voor een toewijzing leveren
- 4VoorbeeldBehoud het deel achter de komma
- 5UitdagingGebruik het resultaat in een andere expressie
- 6VoorbeeldGeef opgemaakte tekst terug
- 7UitlegEen return beëindigt deze aanroep
- 8TipControleer het pad dat de if overslaat
- 9VoorbeeldSchrijf een zoekactie met een resultaat voor mislukking
- 10VoorbeeldVolg de zoekactie tot die eindigt
- 11UitdagingZoek een voortijdige melding van mislukking
- 12UitdagingKoppel een zoekresultaat aan een voorwaarde
- 13SamenvattingVolg zowel het antwoord als het stoppunt
3Houd de variabelen van elke aanroep gescheiden
15 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieKoppel elke variabele aan haar aanroep
- 2UitlegEen hulpmethode ziet haar eigen lokale variabelen
- 3VoorbeeldHoud een totaal buiten de lus
- 4UitdagingOnderscheid bereik van initialisatie
- 5VoorbeeldKopieer een getal naar een parameter
- 6VoorbeeldWijs de teruggegeven vervangende waarde toe
- 7UitdagingVoorspel een tweede aanroep
- 8VerbandGekopieerde referenties volgen dezelfde regel
- 9VoorbeeldBegin een buitenste berekening
- 10VoorbeeldOnderbreek de aanroepende methode en plaats een volgend frame
- 11VoorbeeldGeef resultaten terug naar beneden op de stack
- 12TipLees een fout vanuit het bovenste frame
- 13UitdagingZoek het wachtende werk
- 14UitdagingVerbind kopieën met resultaten op de stack
- 15SamenvattingHoud namen, waarden en frames gescheiden
4Kies de juiste overladen methode
12 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieEén taak, meerdere vormen van invoer
- 2UitlegBepaal een signatuur
- 3KernpuntEen retourtype kan geen overladen methodevariant maken
- 4VoorbeeldDelegeer naar de volledige versie
- 5UitdagingControleer een voorgestelde derde declaratie
- 6UitlegKies een exacte numerieke overeenkomst
- 7VoorbeeldGebruik verbredende zonder versmallende typeconversie
- 8VoorbeeldOnderscheid de aanroep van de toewijzing
- 9VoorbeeldVergelijk elke argumentpositie
- 10TipGebruik de kandidatenlijst om een aanroep te onderzoeken
- 11UitdagingKies een versie en gebruik daarna het resultaat
- 12SamenvattingControleer definities vóór aanroepen
5Bouw een klein rapport met geteste hulpmethoden
16 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieVerdeel een rapport in kleine taken
- 2UitlegBenoem de taak voordat je de methodebody schrijft
- 3VoorbeeldMaak de berekening herbruikbaar
- 4VoorbeeldGeef uitvoer een eigen methode
- 5UitdagingHergebruik een berekening zonder rapport
- 6UitlegZoek wat in herhaalde code verandert
- 7VoorbeeldKies de methodekop voor de geëxtraheerde methode
- 8VoorbeeldZet de gemeenschappelijke lus op één plaats
- 9UitdagingBehoud de laatste herhaling
- 10UitlegPlan het programma van bovenaf
- 11TipGebruik een stub alleen tijdens het bouwen
- 12VoorbeeldGeef dezelfde invoerlezer door
- 13VoorbeeldControleer de berekening voordat je die verbindt
- 14VoorbeeldControleer een invoerreeks in het samengevoegde programma
- 15UitdagingZoek een fout in de samenhang
- 16SamenvattingBouw betekenisvolle onderdelen en verbind ze
Java-methoden: oefenvragen
Set 1: Aanroepen, waarden en kleine programmastappen10 Oefenvragen
Vraag 1 van 10
main-methode en heeft een nieuwe methode printMenu nodig. Waar moet de nieuwe definitie komen?Toon antwoordVerberg antwoord
main aanroept, wordt haar definitie geen deel van main; als je die daar plaatst, ontstaat een geneste methodedefinitie die Java afwijst.Vraag 2 van 10
Welke regel drukt deze aanroep af?
public static void showPair(int rows, int columns) {
System.out.println(rows + ":" + columns);
}
int width = 7;
showPair(3, width - 2);
Toon antwoordVerberg antwoord
rows = 3. De expressie width - 2 wordt vóór de aanroep berekend, dus ontvangt de tweede parameter 5 en is de uitvoer “3:5”. De naam width in de aanroepende code verandert de koppeling van argumenten op positie niet.Vraag 3 van 10
Welke waarde geeft halfTotal(8, 5) terug?
public static double halfTotal(int a, int b) {
return (a + b) / 2;
}
Toon antwoordVerberg antwoord
13 op en delen door de int 2 levert 6 op. Dat resultaat wordt met een verbredende typeconversie omgezet naar de teruggegeven double 6.0. Een retourtype double zorgt er niet voor dat de eerdere deling met kommagetallen rekent; daarvoor zou een deler 2.0 nodig zijn om 6.5 te krijgen.Vraag 4 van 10
Waarom compileert deze methode niet?
public static String label(int n) {
if (n >= 0) {
return "ready";
}
}
Toon antwoordVerberg antwoord
Vraag 5 van 10
Een lus moet de gehele getallen 2 tot en met 4 optellen en daarna het totaal afdrukken. Welke declaratie moet het commentaar vervangen?
// declaration here
for (int i = 2; i <= 4; i++) {
total += i;
}
System.out.println(total);
Toon antwoordVerberg antwoord
total vóór de lus op 0, zodat alle drie optellingen dezelfde variabele bijwerken en die zichtbaar blijft voor de laatste afdrukinstructie. Alleen int total; declareren wijst geen beginwaarde toe, dus zou total += i een niet-geïnitialiseerde lokale variabele lezen.Vraag 6 van 10
Welke twee getallen worden achtereenvolgens afgedrukt?
public static void lower(int level) {
level -= 3;
System.out.println(level);
}
int level = 14;
lower(level);
System.out.println(level);
Toon antwoordVerberg antwoord
level, geïnitialiseerd op 14, verlaagt die kopie naar 11 en drukt die af. De level van de aanroepende code blijft 14 en wordt daarna afgedrukt. Dezelfde naam in beide methoden zorgt er niet voor dat een toewijzing aan de parameter de variabele van de aanroepende code bijwerkt.Vraag 7 van 10
public static int scale(int value). Welke extra methodekop zou met de signatuur daarvan in conflict zijn?Toon antwoordVerberg antwoord
scale(int). Het retourtype double en de gewijzigde parameternaam onderscheiden die niet van de bestaande methode. Het parametertype wijzigen of een parameter toevoegen zou een andere signatuur opleveren.Vraag 8 van 10
show(int n) en show(double n). Welke methode wordt uitgevoerd voor show(12.0)?Toon antwoordVerberg antwoord
12.0 heeft type double, dus is de double-versie een exacte overeenkomst. De geheelgetalswaarde maakt van de expressie geen int. De int-versie zou een versmallende typeconversie vereisen, die Java voor dit argument niet automatisch uitvoert.Vraag 9 van 10
Toon antwoordVerberg antwoord
Vraag 10 van 10
Een programma moet taakduren van 0 tot en met 90 minuten accepteren en het gemiddelde ervan weergeven. Het gebruikt momenteel deze hulpmethoden. Met welke twee aanroepen kun je beide onafhankelijke fouten aan het licht brengen?
public static boolean valid(int m) {
return m > 0 && m <= 90;
}
public static double mean(int total, int count) {
return total / count;
}
Toon antwoordVerberg antwoord
valid(0) geeft ten onrechte false terug, hoewel nul is toegestaan. mean(7, 2) geeft 3.0 terug in plaats van 3.5, omdat de geheeltallige deling vóór de verbredende typeconversie plaatsvindt. Als je valid(90) en dat gemiddelde test, vind je alleen de fout in de deling, omdat de bovengrens al werkt.Set 2: Volg hulpmethoden en herstel methodegrenzen10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Welke reeks regels wordt afgedrukt?
public static void frame() {
System.out.println("Open");
mark();
System.out.println("Close");
}
public static void mark() {
System.out.println("Mark");
}
main roept frame(); aan en drukt daarna "Done" af.
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
public static void repeat(int count). Welke waarde bereikt count in repeat((int) 3.9 + 2);?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Welke waarde wordt aan result toegewezen?
public static int addTwo(int n) {
return n + 2;
}
public static int product(int a, int b) {
return a * b;
}
int result = product(addTwo(4), addTwo(addTwo(1)));
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
De methode moet de eerste even waarde in een bereik inclusief de grenzen teruggeven, of -1 als die er niet is. Voor (9, 12) geeft ze ten onrechte -1 terug. Welke wijziging herstelt de zoekactie?
public static int firstEven(int start, int end) {
for (int n = start; n <= end; n++) {
if (n % 2 == 0) {
return n;
} else {
return -1;
}
}
return -1;
}
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
pages van main staat. Hoe moeten de gegevens de hulpmethode bereiken?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Welke waarde keert vanuit outer(4) terug naar main?
public static int outer(int n) {
int saved = n;
int changed = inner(n + 1);
return saved + changed;
}
public static int inner(int n) {
n *= 2;
return n - 1;
}
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
printBorder(int length, char symbol) met twee argumenten bevat de afdruklus al. Hoe moet printBorder(int length) een standaardwaarde '#' leveren zonder de lus te dupliceren?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Deze overladen methodevarianten staan in dezelfde klasse. Welke waarde wordt in answer opgeslagen?
public static int adjust(int n) { return n + 1; }
public static double adjust(double n) { return n + 0.5; }
double answer = adjust(6);
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
8 * 3 en één met 11 * 4. Beide resultaten zijn nodig voor latere vergelijkingen. Welke methodekop voor een hulpmethode past als je deze gemeenschappelijke berekening onderbrengt in een methode?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
public static int countItems(int limit) { return 0; } een nuttige tijdelijke stub?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Verbind argumenten, returnpaden en ontwerp10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Een programmeur schrijft dit binnen een klasse. Waarom wordt de definitie van de hulpmethode afgewezen?
public static void main(String[] args) {
public static void printTitle() {
System.out.println("Schedule");
}
}
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
De methode geeft het aantal hele groepen terug. Wat geeft groups(5, 18) terug?
public static int groups(int groupSize, int items) {
return items / groupSize;
}
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Een hulpmethode voor een kalender is als volgt geschreven. Welk paar resultaten geven achtereenvolgens leap(2100) en leap(2400) terug?
public static boolean leap(int year) {
return (year % 4 == 0 && year % 100 != 0)
|| year % 400 == 0;
}
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Welke tekst drukt de aanroepende code af?
public static void tag(String name) {
name = name + "-checked";
}
String label = "parcel";
tag(label);
System.out.println(label);
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Een foutrapport begint met ArithmeticException: / by zero en deze frames. Waar vond de deling plaats die mislukte?
at Main.unitCount(Main.java:23)
at Main.printLoad(Main.java:15)
at Main.main(Main.java:5)
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
public static void describe(String name, int count). Welke methodekop voegt een geldige overladen methodevariant toe door de volgorde van de parametertypen te veranderen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Welke regel wordt door deze aanroep afgedrukt? Het teken 'B' heeft de numerieke waarde 66.
public static int code(int n) { return n + 1; }
public static String code(String s) { return s + "!"; }
double result = code('B');
System.out.println(result);
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Het oorspronkelijke programma drukt achtereenvolgens de totalen 20 en 30 af. Nadat code in een methode is ondergebracht, gebruikt het deze hulpmethode. Hoe moeten de twee aanroepen worden geschreven om die totalen te behouden?
public static int sumMultiples(int factor, int count) {
int total = 0;
for (int i = 1; i <= count; i++) {
total += factor * i;
}
return total;
}
De oorspronkelijke eerste lus telde 2, 4, 6 en 8 op. De tweede telde 5, 10 en 15 op.
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Een programma leest vijf dagelijkse aantallen, telt die op en drukt een gemiddelde af. Hieronder staan de geplande methodekoppen van de hulpmethoden. Welke verbinding in main zorgt ervoor dat de rapportagestap alle benodigde gegevens ontvangt?
public static int readCount(Scanner scanner, int day)
public static double average(int total, int days)
public static void printReport(int total, int days)
De Scanner is al aangemaakt.
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Onderzoek volledige interacties tussen methoden10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Welke regel wordt afgedrukt?
public static int next(int n) { return n + 1; }
public static double half(int n) { return n / 2.0; }
int n = 5;
next(n);
double result = half(next(n)) + n;
System.out.println(result);
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Welke waarde geeft locate(5) terug?
public static int locate(int limit) {
int total = 0;
for (int n = 1; n <= limit; n++) {
total += n;
if (total > 8) {
return n;
}
}
return -1;
}
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
De code moet de gewichten optellen en hun som na de lus afdrukken. Momenteel compileert de code niet. Welke wijziging lost het bereikprobleem op en zorgt ervoor dat een lopend totaal wordt bijgehouden?
for (int box = 1; box <= 3; box++) {
int total = 0;
total += box * 2;
}
System.out.println(total);
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Welk paar waarden wordt als a:b afgedrukt?
public static int shift(int n) {
n += 4;
return n;
}
int a = 2;
int b = shift(a);
a = shift(b);
System.out.println(a + ":" + b);
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Wat zijn op het gemarkeerde punt de waarden van de twee lokale variabelen met de naam saved, eerst in het buitenste frame en daarna in het binnenste frame?
public static int outer(int n) {
int saved = n + 2;
return inner(saved) + saved;
}
public static int inner(int n) {
int saved = n * 3;
// program pauses here
return saved;
}
main heeft outer(5) aangeroepen.
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
De onderstaande methoden zijn in één klasse gedeclareerd. Wat gebeurt er bij double result = merge(4, 9);?
public static int merge(int a, double b) { return a; }
public static double merge(double a, int b) { return b; }
public static double merge(double a, double b) { return a + b; }
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
"Crate" af met items genummerd van 1 tot en met 2; het tweede drukt "Bag" af met items genummerd van 1 tot en met 4. Welke geëxtraheerde methodebody behoudt die opmaak voor printItems(String label, int count)?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Een hulpmethode moet een daggemiddelde als kommagetal teruggeven:
public static double dailyAverage(int total, int days) {
return total / days;
}
Waarom brengt controle van alleen (24, 6) de rekenfout niet aan het licht?
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
Aanroepstack
main een hulpmethode aanroept die een andere hulpmethode aanroept, kunnen drie frames tegelijk op de stack staan.Accumulator
sum vóór een lus zodat elke iteratie optelt bij het totaal dat van de vorige herhaling is behouden.Argument
printRepeated("go", 4) leveren de argumenten de tekst en het aantal herhalingen.B
Bereik
Blok
Booleaanse methode
true of false terug, vaak als antwoord op een vraag die de aanroepende code rechtstreeks als voorwaarde gebruikt.isEven(count) kan rechtstreeks tussen de ronde haakjes van een if-instructie worden geplaatst.Bottom-upontwikkeling
D
Decompositie
Delegerende methodevariant
Dubbele code
Dubbelzinnige aanroep
(int, double) en (double, int) maken een aanroep met twee int-argumenten dubbelzinnig.E
Exacte overeenkomst
show(int) en show(double) heeft show(9) een exacte overeenkomst met de int-versie.Expliciete typeconversie (cast)
(int) 4.9 levert 4 aan een int-parameter door het deel achter de komma af te kappen.G
Geneste aanroep
Math.max(sum(2, 6), 5) wordt het resultaat 8 het eerste argument van Math.max.Grensgeval
-1, 0, 1440 en 1441 als afzonderlijke invoer.H
Hulpmethode
I
Incrementele ontwikkeling
Initialisatie
int total = 0; vóór een optellus heeft de eerste optelling een bestaand totaal om bij te werken.J
Javadoc
/** ... */-commentaar boven een declaratie, met tags die parameters en resultaten beschrijven.@param minutes om invoer uit te leggen en @return om de opgemaakte tekst te beschrijven die de methode oplevert.L
Laatst erin, eerst eruit (lifo)
Lokale variabele
total in een hulpmethode staat los van een lokale variabele in een andere methode die ook total heet.M
Methode
printHeader() kan op meerdere plaatsen in een programma dezelfde rapportkop afdrukken.Methode-extractie
sumUpTo(int n), blijft de aanroepende code verantwoordelijk voor haar eigen rapporttekst.Methodeaanroep
printHeader(); voert de methode die de kop afdrukt uit op dat punt in de aanroepende code.Methodebody
Methodekop
public static void greet() beschrijft een aanroepbare handeling zonder invoer en zonder retourwaarde.Methodesignatuur
width verandert in w, blijft area(int, int) onveranderd en ontstaat geen nieuwe overladen methodevariant.O
Onbereikbare instructie
Onveranderlijke String
"!" met een String samenvoegt en het resultaat aan een String-parameter toewijst, blijft de referentie van de aanroepende code onveranderd.Overladen
max kunnen twee ints en drie ints accepteren terwijl de naam één betekenis behoudt.P
Parameter
printRepeated(String text, int times) zijn text en times de twee gedeclareerde parameters.Parameterlijst
(int width, int height) vereist twee argumenten, die eerst aan width en daarna aan height worden gekoppeld.Privémethode
private static declareert, kan haar eigen klasse die gebruiken zonder een externe aanroep aan te bieden.R
Refactoring
Referentie
Retourtype
void geeft aan dat ze geen waarde levert.double average(int a, int b) belooft de aanroepende code een double-resultaat.Retourwaarde
int total = sum(6, 8); wordt de teruggegeven 14 opgeslagen in de variabele total van de aanroepende code.return-instructie
return minutes * 60; beëindigt de berekening en levert het aantal seconden.S
Selectie van een overladen methode
Signaalwaarde
-1 geen geldige overeenkomst kan zijn, kan het teruggeven van -1 na een zoekactie “niet gevonden” aangeven.Stackframe
minutes hebben omdat de parameters in afzonderlijke frames staan.Stackoverloop
StackOverflowError oplevert.Stacktrace
Statische methode
Math.abs(-6) gebruikt de klassenaam Math en geeft de positieve waarde 6 terug.Stub
return 0; kan de plaats innemen van de echte berekening terwijl die wordt geïmplementeerd en gecontroleerd.T
Top-downontwerp
main voordat je de methodebody’s van de hulpmethoden invult.V
Verbredende typeconversie
12 aan een double-parameter doorgeeft, krijgt die 12.0 zonder dat een expliciete typeconversie nodig is.Versmallende typeconversie
9.0 zonder expliciete typeconversie aan een int-parameter doorgeeft, mislukt dat, ook al heeft de waarde geen deel achter de komma.void
printTotal kan de rechterkant van een int-toewijzing niet vullen alleen omdat die een getal afdrukt.Voortijdige terugkeer
return candidate; wordt uitgevoerd, ook als de lus nog meer kandidaten heeft.W
Waardeoverdracht
- 1Eerste Java-programma’s
- 2Voorwaarden en lussen in Java
- 3Java-methoden
- 4Lijsten, arrays en strings in Java
- 5Java-klassen en objecten
- 6Objecten, referenties en gelijkheid in Java
- 7HashMaps en collecties in Java
- 8Overerving in Java
- 9Excepties en bestanden in Java
- 10Klassendiagrammen en unittests in Java
- 11Lambda-expressies en streams in Java
Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.