Avatar billede trp79 Nybegynder
25. juni 2003 - 14:04 Der er 30 kommentarer og
1 løsning

Fange Integer.parseInt exception

Hejsa,
Er det pænt at fange en fejl på følgende måde?
try{
  totalOms+=Integer.parseInt(oms.getOms());}
catch(Exception e){System.out.println("År mangler omsaetning: "+e);
}

try{
totalBudget+=Integer.parseInt(bud.getBudget());}
    catch(Exception e){System.out.println("År mangler budget: "+e);
}

Hvad er alternativet til dette ellers?
Avatar billede riversen Nybegynder
25. juni 2003 - 14:08 #1
den kaster en NumberFormatException, men det er måden at gøre det på. NumberFormatException er dog en RuntimeException så den skal ikke gribes
Avatar billede trp79 Nybegynder
25. juni 2003 - 14:30 #2
Hvad vil så være mest korrekt at gøre i mit tilfælde?
jeg kan jo ikke bare undlade try catchen... jeg får i hvert fald en nullpointer exception. Den kommer vel fordi den ikke kan sige += hvis et tal ikke kan parses til en int?
Avatar billede riversen Nybegynder
25. juni 2003 - 14:42 #3
nej, du kan ikke undlade at gribe den, hvis du vil fortage noget ud fra den exception. Det bedste er at sige catch( NumberFormatException e ) istedet for bare Exception e
Avatar billede fsconsult.dk Nybegynder
25. juni 2003 - 14:46 #4
selvom det er en RuntimeException skal den da gribes alligevel hvis det er relevant.

man kunne dog evt. indkapsle det i en metode:
totalOms+=handleConvertion(oms.getOms(),"År mangler omsætning");
totalBudget+=handleConvertion(oms.getBudget(),"År mangler budget");

public handleConvertion(String txt, String errorMsg) {
  try{
    totalOms+=Integer.parseInt(txt);}
  catch(NumberFormatException ex){System.out.println(errroMsg + ": "+e);
    return 0;
  }

}
Avatar billede fsconsult.dk Nybegynder
25. juni 2003 - 14:46 #5
prøver lige igen:

public static int handleConvertion(String txt, String errorMsg) {
  try{
    totalOms+=Integer.parseInt(txt);}
  catch(NumberFormatException ex){System.out.println(errroMsg + ": "+e);
    return 0;
  }

}
Avatar billede jakoba Nybegynder
25. juni 2003 - 14:49 #6
Det er helt fint at fange alle de exceptions du ønsker og gøre noget fornuftigt ved dem istedet for blot at lade programmet dø.

Du kan fange exceptions udfra deres navn. enten fordefinerede navne som NullPointerException eller navne du selv laver ved selv at extende klassen Exception som nedenfor.

class TalletErForStort extends Exception {
    TalletErForStort(  ) {
        super();
    }
} // endclass TalletErForStort

class TestExceptions {
   
    static int maxIndex = 9;
    static int[] eksempelArray = new int[maxIndex+1];

    static int findVerdi ( int index ) throws TalletErForStort, Exception {
        if ( index > maxIndex ) throw new TalletErForStort() ;
        if ( index < 0 ) throw new Exception();
        return eksempelArray[ index ];
    }

    public static void main ( String[] args ) {
        for ( int i=0; i<=maxIndex; i++ ) eksempelArray[i] = 100 + i;

        try {
            System.out.println( "med index = 25" );
            System.out.println( findVerdi(25) );
        } catch ( TalletErForStort e ) {
            System.out.print( "for stort index\n" );
            e.printStackTrace();
        } catch ( Exception e ) {
            System.out.println( "det gok galt. Jeg aner ikke hvorfor." );
        }
       
        try {
            System.out.println( "med index = -5" );
            System.out.println( findVerdi(-5) );
        } catch ( TalletErForStort e ) {
            System.out.println( "for stort index\n" );
            e.printStackTrace();
        } catch ( Exception e ) {
            System.out.println( "det gok galt. Jeg aner ikke hvorfor." );
        }
       
        try {
            System.out.println( "med index = 7" );
            System.out.println( findVerdi(7) );
        } catch ( TalletErForStort e ) {
            System.out.println( "for stort index\n" );
            e.printStackTrace();
        } catch ( Exception e ) {
            System.out.println( "det gok galt. Jeg aner ikke hvorfor." );
        }
    }

} //endclass TestExceptions
Avatar billede trp79 Nybegynder
25. juni 2003 - 14:49 #7
-->fsconsult
Jeg kan godt se det smarte i indkapslingen, men hvorfor static?
Avatar billede arne_v Ekspert
25. juni 2003 - 14:49 #8
catch( NumberFormatException e )

er vel den eneste måde at gøre det på med det pågældende
objekt.

Men måske er der andre muligheder ?

Du har:
  public String getOms()
og en konvention om at "-" betyder ingen data (eller lignende).

men måske var det pænere med:
  public boolean isOms()
  public int getOms()
??
Avatar billede trp79 Nybegynder
25. juni 2003 - 14:53 #9
En anden ting er at det ikke funker hvis jeg erstatter "catch(Exception e)" med "catch(NumberFormatException e)". Burde det ikke det?
Avatar billede fsconsult.dk Nybegynder
25. juni 2003 - 14:55 #10
trp79 >> static er ikke nødvendigt, men da metoden ikke har brug for andre data end dem den får fra metode kaldet, gør static det muligt at benytte metoden fra andre klasser, uden først at skulle instantiere et nyt objekt af din klasse.
Avatar billede trp79 Nybegynder
25. juni 2003 - 14:57 #11
--> Arne
Ja det var da en forrygende ide. Hvis jeg nu laver en boolean metode, der returnerer true eller false alt afhængig af om det strengen kan parses eller ej.

Jeg synes bare jeg har hørt at det er dårlig skik at fange fejl med en exception - men det gælder måske kun hvis de ikke er nærmere defineret som ved catch(Exception e) ?

En hel anden ting... er det ikke lidt underligt at man ikke har lavet parseInt sådan at den returnerer null hvis strengen ikke kan parses? eller er der en logisk forklaring på det?
Avatar billede trp79 Nybegynder
25. juni 2003 - 14:57 #12
--> fsconsult.dk
Okey selvfølgelig :o)
Avatar billede arne_v Ekspert
25. juni 2003 - 15:00 #13
Mystisk.

Følgende virker hos mig:

public class NumTest {
    public static void main(String[] args) {
        test("123");
        test("abc");
    }
    public static void test(String s) {
        try {
            int v = Integer.parseInt(s);
            System.out.println(s + " is a number");
        } catch (NumberFormatException e) {
            System.out.println(s + " is not a number");
        }
    }
}
Avatar billede arne_v Ekspert
25. juni 2003 - 15:01 #14
parseInt kan ikke returnere null, da den returnerer int og kun objekter
kan være nul (ikke simple data typer).
Avatar billede arne_v Ekspert
25. juni 2003 - 15:03 #15
Man skal være lidt forsigtig med hvad man fanger og specielt hvor man
fanger det.

Men hvis aldrig man skulle bruge exceptions, så var der jo ikke nogen
grund til at de var i sproget.
Avatar billede arne_v Ekspert
25. juni 2003 - 15:06 #16
Jeg lavede følgende kode til at sammenligne hastighed for nogle
måneder siden:

public class IntegerTest {
    private static final int antal = 1000000;

    private static final String goodtext = "12345";
    private static final String badtext = "12345a";

    private static void test(String text) {
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < antal; i++) {
            int tal = test1(text);
        }
        long stop1 = System.currentTimeMillis();
        long start2 = System.currentTimeMillis();
        for (int i = 0; i < antal; i++) {
            int tal = test2(text);
        }
        long stop2 = System.currentTimeMillis();
        long start3 = System.currentTimeMillis();
        for (int i = 0; i < antal; i++) {
            int tal = test3(text);
        }
        long stop3 = System.currentTimeMillis();
        System.out.println("test 1 (try/catch)  = " + (stop1 - start1));
        System.out.println("test 2 (homemade)= " + (stop2 - start2));
        System.out.println("test 3 (isDigit()) = " + (stop3 - start3));
    }
    private static int test1(String s) {
        try {
            return Integer.parseInt(s);
        } catch (NumberFormatException e) {
            return -1;
        }
    }
    private static int test2(String s) {
        for (int j = 0; j < s.length(); j++) {
            if (s.charAt(j) < '0' || s.charAt(j) > '9') {
                return -1;
            }
        }
        return Integer.parseInt(s);
    }
    private static int test3(String s) {
        for (int j = 0; j < s.length(); j++) {
            if (!Character.isDigit(s.charAt(j))) {
                return -1;
            }
        }
        return Integer.parseInt(s);
    }
    public static void main(String[] args) {
        System.out.println("All good:");
        test(goodtext);
        System.out.println("All bad:");
        test(badtext);
    }
}
Avatar billede jakoba Nybegynder
25. juni 2003 - 15:09 #17
En helt anden ting >>  der er ihvertfald en 'religiøs' forklaring :-))

Mange (og også jeg) ser det som direkte forkert når et programmeringssprog prøver at gætte hvad brugeren ønsker.
sålænge et program er ekstremt kort gør det ikke noget. I javascript kan du fx gange en streng med et tal, og sproget vil så gætte sig til at den streng nok kan konverteres til en numerisk værdi der kan ganges. og gøre det uden af fortælle dig noget om gætteriet.
    alert( "25" * 75 );  // virker fint i javascript.
men hvad med:
    alert( "2" + "2" );  // mener programmøren "22" eller tallet 4 ?
                    // javascript gætter på "22"
Det gætteri giver fejl nu og da.
Og eftrerhånden som de programmer der skrives bliver større bliver den slags 'hjælp' mere og mere farlig. og programmet bliver sværerere at debugge fordi der ikke nødvendigvis kommer en fejlmelding der hvor du lavede fejl. men istedet lang senere hvor den fejl har en konsekvens programmet ikke kan gætte sig udenom.

At returnere nul ved parseint af en ugyldig streng ville også være et sådant gæt. "mon ikke han kan bruge et nul istedet".

mvh JakobA
Avatar billede riversen Nybegynder
25. juni 2003 - 15:09 #18
fsconsult.dk: vedr. 25/06-2003 14:46:00...er der da nogen der har påstået noget andet?
Avatar billede arne_v Ekspert
25. juni 2003 - 15:11 #19
Min ide med isOms() var dok ike så meget at de skulle være
en indkapsling af hverken det ene eller det andet test.

Men derimod at:

public class Omsaetning {
  private int oms;
  private boolean omsset;
  public Omsaetning() {
      omsset = false;
  }
  public boolean isOms() {
      return omsset;
  }
  public int getOms() {
      return oms;
  }
  public void setOms(int oms) {
      this.oms = oms;
      omsset = true; // <------- pointen
  }
}

Og pointen er ved altid at bruge int så undgår man helt konvertering og at
set'eren holder styr på hvornår der er en valid værdi.
Avatar billede arne_v Ekspert
25. juni 2003 - 15:13 #20
Jakoba - han mener null ikke nul.

[ja - og det er muligvis min skyld fordi jeg glemte et "l" til sidst
i min 15:01:47 kommentar]
Avatar billede fsconsult.dk Nybegynder
25. juni 2003 - 15:13 #21
riversen> du skrev "NumberFormatException er dog en RuntimeException så den skal ikke gribes". du korrigerede det dog også mens jeg var ved at skrive min første kommentar
Avatar billede riversen Nybegynder
25. juni 2003 - 15:14 #22
fsconsult.dk: den skal heller ikke gribes...
Avatar billede trp79 Nybegynder
25. juni 2003 - 15:21 #23
Okey, mit program virker med catch(Exception e) men ikke med catch(NumberFormatException e) kan det så skyldes at jeg har en anden fejl?
jeg synes at det er lidt underligt.

Ja, det ville nok have været lidt mere smart hvis jeg arbejdede med int hele vejen igennem når der var tale om tal.... men ja, det vil tage adskillige timer at ændre det i de ca. 4000 linier kode jeg har nu....
Avatar billede trp79 Nybegynder
25. juni 2003 - 15:22 #24
Den skriver en nullpointer exception ud... det må næsten være et helt andet sted i koden så eller?
Avatar billede arne_v Ekspert
25. juni 2003 - 15:24 #25
Hov.

Nu ligger jeg lige 2 og 2 sammen og får 4.

Dit problem er slet ikke om getOms() returnerer en streng der
et valid tal eller ej.

Dit problem er om oms er null !
Avatar billede trp79 Nybegynder
25. juni 2003 - 15:25 #26
den kommer også med nullpointer exceptionen når jeg bruger catch(exception e). Men når jeg bruge catch(exception e) genererer programmet et html dokument som det skal, men når jeg bruger catch(numberfor....) så genererer den ikke html dokumentet. :-/
Avatar billede arne_v Ekspert
25. juni 2003 - 15:26 #27
Så du skal nok have noget kode a la:

if(oms != null) {
  // kald oms.getOms()
} else {
  // vi har ikke noget
}
Avatar billede trp79 Nybegynder
25. juni 2003 - 15:28 #28
--> Arne
Du har så evig ret :o)
Det er jo forrygende, tak for hjælpen.

Jeg ved ikke om folk har lyst til at smide et svar, nu har jeg da både lært noget om exceptions og noget om simple datatyper (at de ikke kan returnere null....)
Avatar billede arne_v Ekspert
25. juni 2003 - 15:30 #29
Med hensyn til hvad man skal catche og ikke catche, så er der forskellige
opfattelser af dette, men efter min mening bruges der alt for meget tid
på at diskuetere dette og for lidt tid på at diskutere på hvilket
niveau i programmet man skal catche. Det er helt afgørende både for at få nogle
brugbare fejlbeskeder ud og for at kunne recovere fornuftigt.
Avatar billede arne_v Ekspert
25. juni 2003 - 15:32 #30
svar
Avatar billede trp79 Nybegynder
25. juni 2003 - 19:09 #31
Ok, det tyder ikke på at fsconsult og riversen vil have del i pointene så de går til dig arne.

I må have tak for hjælpen, mvh
Torben
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester