Toon posts:

[Java] Simpel vraagje

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0Henk 'm!

  • Skatespeare
  • Registratie: Juli 2009
  • Laatst online: 23-04 14:46
Van de week besloten mij eens te gaan verdiepen in Java. Gewoon voor de lol. Ik ben geen programmeur en kan hooguit een beetje PHP, maar Java leek me wel leuk. Dus ik ben nu aan de gang gegaan met zo'n noob boek en ik krijg er wel plezier in, maar ik loop nu tegen een raar probleem aan uit een voorbeeld. Als ik deze code run krijg ik de error
code:
1
2
3
How old are you? 20
Have a coupon? (Y/N) Exception in thread "main" java.lang.NullPointerException
        at CheckAgeForDiscount.main(CheckAgeForDiscount.java:15)

De code zou moeten werken, omdat ie letterlijk uit het boek komt dus ik heb het idee dat er iers anders aan de hand is. Iemand enig idee? Dit is de hele code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Scanner;

class CheckAgeForDiscount {

    public static void main(String args[]) {
        Scanner myScanner = new Scanner(System.in);
        int age;
        double price = 0.00;
        char reply;

        System.out.print("How old are you? ");
        age = myScanner.nextInt();

        System.out.print("Have a coupon? (Y/N) ");
        reply = myScanner.findInLine(".").charAt(0);

        if (age >= 12 && age < 65) {
            price = 9.25;
        }
        if (age < 12 || age >= 65) {
            price = 5.25;
        }

        if ((reply == 'Y' || reply == 'y') &&
            (age >= 12 && age < 65)) {
            price -= 2.00;
        }

        System.out.print("Please pay $");
        System.out.print(price);
        System.out.print(". ");
        System.out.println("Enjoy the show!");
    }
}

Acties:
  • 0Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-05 17:03

NMe

Quia Ego Sic Dico.

Dan ga je debuggen en kom je er vanzelf achter dat op regel 15 ofwel myScanner null is, ofwel de returnwaarde van findInLine.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
De foutmelding zegt dat er ergens op regel 15 een fout zit; er is iets null. De regel in kwestie:

Java:
1
reply = myScanner.findInLine(".").charAt(0);


Je weet dat myScanner niet null is, deze gebruik je op regel 12 ook om een getal te krijgen. Het kan dus zijn dat de findInLine methode null returned en je de eerste karakter van niets probeert op te vragen.

Deze aannames kan je verifieren door in je editor dit te loggen, of breakpoints te zetten. Debuggen dus :Y)

De fout is dus dat je probeert een punt te zoeken in de tekst die je binnenkrijgt, maar deze niet kan vinden. Je kan dit fixen door eerst er een try .. catch omheen te plaatsen, het is immers mogelijk dat een gebruiker geen punt invult. Let wel dat het niet erg netjes is om overal maar try-catches omheen te zetten als het niet werkt, maar in dit geval heb je een redelijk excuus.

[Voor 31% gewijzigd door TJHeuvel op 07-06-2011 17:29]

Freelance Unity3D developer


Acties:
  • 0Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-05 17:03

NMe

Quia Ego Sic Dico.

CyCloneNL schreef op dinsdag 07 juni 2011 @ 17:25:
De fout is dus dat je probeert een punt te zoeken in de tekst die je binnenkrijgt, maar deze niet kan vinden. Je kan dit fixen door eerst er een try .. catch omheen te plaatsen, het is immers mogelijk dat een gebruiker geen punt invult. Let wel dat het niet erg netjes is om overal maar try-catches omheen te zetten als het niet werkt, maar in dit geval heb je een redelijk excuus.
Dat is helemaal geen redelijk excuus. Exceptions zijn voor uitzonderingssituaties. Een gebruiker die een foute waarde doorgeeft is niet uitzonderlijk en zou al helemaal niet onverwacht mogen zijn.

Gewoon vooraf checken wat je terugkrijgt voordat je er operaties op gaat doen.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 10:02
O en een tip:
Code in de meeste boeken zit vol met fouten. Ga er dus ook niet meteen vanuit dat iets moet werken, omdat je het precies hebt overgetypt en ga ook niet zomaar alles klakkeloos overnemen, maar probeer te begrijpen wat er gebeurd en het zelf te maken.

Acties:
  • 0Henk 'm!

  • Skatespeare
  • Registratie: Juli 2009
  • Laatst online: 23-04 14:46
Bedankt voor de hulp. Ik ga me eerst maar eens in debugging van Java verdiepen voor ik verder ga.

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
CyCloneNL schreef op dinsdag 07 juni 2011 @ 17:25:
De foutmelding zegt dat er ergens op regel 15 een fout zit; er is iets null. De regel in kwestie:

Java:
1
reply = myScanner.findInLine(".").charAt(0);


Je weet dat myScanner niet null is, deze gebruik je op regel 12 ook om een getal te krijgen. Het kan dus zijn dat de findInLine methode null returned en je de eerste karakter van niets probeert op te vragen.

Deze aannames kan je verifieren door in je editor dit te loggen, of breakpoints te zetten. Debuggen dus :Y)

De fout is dus dat je probeert een punt te zoeken in de tekst die je binnenkrijgt, maar deze niet kan vinden. Je kan dit fixen door eerst er een try .. catch omheen te plaatsen, het is immers mogelijk dat een gebruiker geen punt invult. Let wel dat het niet erg netjes is om overal maar try-catches omheen te zetten als het niet werkt, maar in dit geval heb je een redelijk excuus.
De parameter van Scanner#findInLine() is een regex pattern. In dit geval wordt dus gezocht naar een enkel willekeurige karakter.

Het probleem is dat findInLine(pattern) alleen kijkt naar wat er nu beschikbaar is, en als de gebruiker dus niks ingevoerd heeft op het moment dat regel 15 wordt uitgevoerd (wat over het algemeen zo is), dan wordt er geen match gevonden voor het pattern en dus null geretourneerd.

Gegeven het doel kan findInLine(pattern) beter vervangen worden met next() of misschien next(".") (al lijkt mij dat niet zo nuttig gegeven de applicatie). Je moet dan alleen nog wel rekening houden met gebruikers die een lege regel ingeven!

  • Mammon
  • Registratie: December 2006
  • Laatst online: 26-05 09:43
Als je myScanner.nextInt(); uitvoert blocked het programma tot dat het weer wat beschikbaar komt in de InputStream die de scanner gebruikt. In dit geval System.in. Jij voert dan 20 in maar wat je in werkelijkheid invoert is 20\n vanwege de enter. De volgende call naar findInLine() leest dan die \n maar negeert die (wat netjes gedocumenteerd is). Vervolgens returned die methode nullen als je dan daarop charAt() op aanroept resulteert dat in een NullPointerException.

Een fix is:
Java:
1
2
3
4
System.out.print("How old are you? ");
age = myScanner.nextInt();

myScanner.nextLine();
Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee