Avatar billede jime_boy Nybegynder
14. juni 2005 - 18:25 Der er 19 kommentarer og
1 løsning

Den returnere false selvom det burde være true.

Jeg skal lave en metode som skal tjekke i en database om et givent id eksistere. Jeg har oprette test data i databasen og har kørt metoden nogle gange for at se om den fra databasen henter de rigtige oplysninger og det gør den. Derfor antager jeg at der ligger en fejl i java'en. metoden ser således ud:

public boolean eksistere_id(String forkortelse)
    {
        String a="";
        try
        {
            Statement s= forb.con.createStatement();
   
            ResultSet rs= s.executeQuery("SELECT tekst_id FROM kilder WHERE kilder.tekst_id='"+forkortelse+"'");
           
            while (rs.next())
            a= new String(rs.getString(1));   
           
        }
        catch(Exception ex){}
               
        if(a==forkortelse){return true;}
        else{ return false;}
    }

Er der nogen der kan se hvorfor den returnere false hver gang?
Avatar billede simonvalter Praktikant
14. juni 2005 - 18:27 #1
du sammenligner strings med .equals

if(a.equals(forkortelse)){
}else {

}
Avatar billede nielle Nybegynder
14. juni 2005 - 18:29 #2
while (rs.next())
    a= new String(rs.getString(0));a= new String(rs.getString(0));
Avatar billede nielle Nybegynder
14. juni 2005 - 18:29 #3
Indeks 0 i stedet for 1:

while (rs.next())
    a= new String(rs.getString(0));
Avatar billede schwarz84 Nybegynder
14. juni 2005 - 18:32 #4
Uddybelse af simonvalters kommentar: equals tester om inholdet af to strenge er ens (om der står det samme), mens = tester om der er tale om det samme objekt. Du kan sagtens have to stringobjekter med samme inhold, og da der altså er tale om to forskellige stringobjekter returnerer din metode false, selvom equals er true.
Avatar billede nielle Nybegynder
14. juni 2005 - 18:32 #5
public boolean eksistere_id(String forkortelse)
{
    String a= "";
    try
    {
        Statement s= forb.con.createStatement();
   
        ResultSet rs= s.executeQuery("SELECT tekst_id FROM kilder WHERE kilder.tekst_id='" + forkortelse + "'");
           
        while (rs.next())
        {
            a= new String(rs.getString(0));
            if (a == forkortelse) return true;
        }
    }
    catch(Exception ex){}

    return false;
}
Avatar billede nielle Nybegynder
14. juni 2005 - 18:33 #6
Bortset fra at du så nok skal bruge equals, så er det vigtigt at du får din sammenligning *indenfor* i din while-loop.
Avatar billede schwarz84 Nybegynder
14. juni 2005 - 18:35 #7
Et andet eksempel:

String a,b;
a = "foo";
b = a;
Her vil a == b give true og a.equals(b) vil give true.

String a,b;
a = "foo";
b = "foo";
Her vil a == b give false da, der er tale om to forskellige stringobjekter, men a.equals(b) vil give true.

Jeg tager i ovenstående forbehold for evt. optimering fortaget af kompileren (måske kan den finde på at pege a og b på samme objekt for at optimere), men princippet er som beskrevet og det er det du løber ind i med din metode.
Avatar billede nielle Nybegynder
14. juni 2005 - 18:39 #8
My bad der er ikke 0, men 1:

rs.getString(1)

- eller endnu bedre:

rs.getString("tekst_id")
Avatar billede jime_boy Nybegynder
14. juni 2005 - 18:47 #9
jeg takker, jeg kan helt sikkert bruge alle svarene.
Avatar billede nielle Nybegynder
14. juni 2005 - 18:48 #10
Svar :^)
Avatar billede arne_v Ekspert
14. juni 2005 - 18:54 #11
JDBC er altid et baseret aldrig nul baseret.

Det anses som best practice at bruge kolonne index og ikke kolonne navn.

a = new String(rs.getString(1));

bør skrives som

a = rs.getString(1); 

da der ikke er nogen grund til at lave en ny string.

simons forklaring er den rigtige - det virker med:

if(a.equals(forkortelse)){

a = "foo";
b = "foo";

vil *altid* blive optimeret til at pege på samme objekt.
Avatar billede mikkelbm Nybegynder
14. juni 2005 - 19:00 #12
Arne

Jeg vil da mene, at det er mere sikkert at bruge kolonnenavn, for så kan man være ligeglad med rækkefølgen i select sætningen. Og for mit eget vedkommende, er det også sådanne eksempler jeg har set flest af.
Avatar billede arne_v Ekspert
14. juni 2005 - 19:13 #13
det er der flere grunde til

1)  performance - det koster lidt at slå navn op

2)  risiko for stave fejl som giver runtime fejl

3)  navne uklarhed (multi table joins, expressions etc.)
Avatar billede simonvalter Praktikant
14. juni 2005 - 19:53 #14
Der er vist kun få tilfælde hvor det kan betale sig at lave en ny string ud af en string. Et interessant eksempel kan man se her
http://www.eclipse.org/eclipse/development/performance/bloopers.html
se: Blooper: String.substring()
Avatar billede arne_v Ekspert
14. juni 2005 - 20:08 #15
det er vist et special tilfælde hvis noget er

:-)
Avatar billede arne_v Ekspert
14. juni 2005 - 20:08 #16
og hvis jeg nu skal igang med at grynte over hvad som helst så er

catch(Exception ex){}

farlig !
Avatar billede jime_boy Nybegynder
14. juni 2005 - 20:40 #17
meningen med catch(Exception ex){} er at jeg ville sætte en JOptionPane.showMessageDialog(this,ex); ind i, så den sparker en exception ud på skærmen. Jeg er bare ikke nået så langt endnu, det meste står stadig på papir. :-)
Avatar billede nielle Nybegynder
14. juni 2005 - 20:42 #18
Jeg tror nu mest at Arne_v grynter over at du bruger den helt brede "Exception" og ikke en meget snæver som rammer lige præcis de/n exception du kan få i det konkrete tilfælde.
Avatar billede nielle Nybegynder
14. juni 2005 - 20:44 #19
Takker for point, men var der ikke nogen af jer andre som også ville have? Jeg deler da gerne. :^)
Avatar billede arne_v Ekspert
14. juni 2005 - 22:07 #20
Det er ikke særligt pænt at catche så bredt at man får RuntimeException's med, men
det går nu nok på dette her niveau.

Det var faktisk den tomme {} jeg tænkte på. Vi har set mange mange spørgsmål her
på Eksperten hvor man fik nogle mystiske fejl og så viste det sig at de skyldtes
tidligere execeptions som bare var blevet slugt uden at efterlade sig spor.
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