[Java] evalueren van een if-statement

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Marc
  • Registratie: November 2001
  • Laatst online: 01-12-2021
Ik ben enigszins verbaast over de manier waarop Java een if-statement evalueert, en ik hoop dat iemand mij kan vertellen waarom Java het op deze manier doet. Neem bijvoorbeeld de volgende code (i is een globale variable):

Java: example1
1
2
3
4
5
6
7
8
9
10
int i = 0;
if (change() && (i == 5))
   System.out.println("yah");

...

private boolean change() {
   i = 5;
   return true;
}


Dit zal nooit "yah" printen, terwijl ik hier eigenlijk wel op hoopte. Ik verwachtte namelijk dat Java eerst de eerste conjunct volledig evalueert, en afhankelijk van het resultaat daarvan de tweede (wanneer de eerste faalt kan de tweede namelijk genegeerd worden), maar nu krijg ik het idee dat ze beiden tegelijk ge-evalueert worden.

Acties:
  • 0 Henk 'm!

Verwijderd

Gebeurt dit ook als je de haakjes rond (i == 5) weghaald? Ik vermoed dat die een hogere prioriteit krijgt door de haakjes.

Acties:
  • 0 Henk 'm!

  • OrbitZ
  • Registratie: Juni 2001
  • Laatst online: 26-05 13:07
Java:
1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
    static int i = 0; 
    public static void main(String[] args) {
        if (change() && (i == 5))
           System.out.println("yah"); 
    }
    
    private static boolean change() { 
        i = 5; 
        return true; 
    }
}


= yah


Java:
1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
    static int i = 0; 
    public static void main(String[] args) {
        if ((i == 5) && change()) 
           System.out.println("yah"); 
    }
    
    private static boolean change() { 
        i = 5; 
        return true; 
    }
}


= niks

De code in if statements worden van links naar rechts geëvalueerd.

Acties:
  • 0 Henk 'm!

  • Marc
  • Registratie: November 2001
  • Laatst online: 01-12-2021
Je hebt gelijk Orbitz, maar het verschil zit hem hierin:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class T { 
    static int i;  
    public static void main(String[] args) { 
        i = 0;
        if ((i == 5) && change())  
           System.out.println("yah");  
    } 
     
    private static boolean change() {  
        i = 5;  
        return true;  
    } 
}


Nu geeft hij geen "yah"... gek toch?

Acties:
  • 0 Henk 'm!

  • CoolGamer
  • Registratie: Mei 2005
  • Laatst online: 12-10 15:22

CoolGamer

What is it? Dragons?

Hij kijkt eerst aan de linker kant van &&, daarna pas aan de rechter kant als de linker kant waar is. Dus als je i op 0 zet, dan levert de linker kant false op. De rechterkant wordt dan niet eens meer uitgevoerd.

¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸


Acties:
  • 0 Henk 'm!

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:17
Marc schreef op dinsdag 05 juni 2012 @ 22:42:
Je hebt gelijk Orbitz, maar het verschil zit hem hierin:

[...]

Nu geeft hij geen "yah"... gek toch?
Nee,
OrbitZ schreef op dinsdag 05 juni 2012 @ 22:38:
De code in if statements worden van links naar rechts geëvalueerd.
En i is daar niet gelijk aan vijf.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Hoezo is dat gek? Je hebt hier met 2 zaken te maken: scope en short circuiting.

Met alle respect, maar als je de basis niet goed begrijpt zou ik 't voortaan eerst even bij mezelf zoeken in plaats van Java (of eender welke taal) de schuld te geven ;) Dit soort zaken zijn écht wel uitgekristalliseerd na jaren en miljoenen gebruikers :Y)

[edit]
Ondertussen spuit 11 :P

[ Voor 54% gewijzigd door RobIII op 05-06-2012 22:49 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Ozzie
  • Registratie: Februari 2004
  • Laatst online: 23:08
Het voorbeeld in je startpost zou gewoon in de if moeten komen hoor.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
    private int i = 0;

    public Test() {
        if (change() && (i == 5)) {
            System.out.println("Bla");
        }
    }

    public boolean change() {
        i = 5;
        return true;
    }


Dit geeft bij mij gewoon 'Bla' in de sys.out

/edit volgende keer eerst kijken of er nog geen antwoorden zijn gegeven :)

[ Voor 11% gewijzigd door Ozzie op 05-06-2012 22:52 ]

"Write code as if the next maintainer is a vicious psychopath who knows where you live."


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ozzie schreef op dinsdag 05 juni 2012 @ 22:51:
Dit geeft bij mij gewoon 'Bla' in de sys.out
Wat aangeeft dat in z'n startpost een scope probleem aanwezig is (of: moet zijn). En wanneer 'ie dat fixed draait 'ie stiekem in z'n tweede post de condities om :o

[ Voor 9% gewijzigd door RobIII op 05-06-2012 22:54 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 23-09 09:07

Kajel

Development in Style

Mocht je overigens willen dat wel beide operands geëvalueerd worden, dan kun je "&" gebruiken in het geval van AND en "|" in het geval van OR. Dit is uiteraard minder efficient.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik zie niet helemaal hoe short-circuiting hier relevant is eigenlijk. Ook zonder short-circuit (door gebruik van een & ipv een && bijvoorbeeld) zal het resultaat gelijk zijn, want de expressies worden nou eenmaal van links naar rechts geëvalueerd.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 19-09 10:19
Sowieso wil ik nog even opmerkingen dat if statements die de state van je programma veranderen echt uit den bozen zijn en een grote bron van moeilijk vindbare bugs. Dit concept heeft ook wel side-effects en is een anti-pattern.

Wikipedia: Side effect (computer science)

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sorry maar dat vind ik echt nergens op slaan.

code:
1
2
3
4
if (ChangeSomething())
    Succeeded();
else
    Failed();

Uit den boze dus?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 23:34
Je zou er het volgende van kunnen maken:
code:
1
2
3
4
5
6
bool success = ChangeSomething());

if (success)
    doe iets
else
    doe iets anders

Maar of dat nou veel beter is? :P

[ Voor 10% gewijzigd door Caelorum op 06-06-2012 15:01 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Dan is het nog steeds een if-statement dat de state van je programma verandert, dus dat is nou niet echt een schokkende wijziging behalve dat het meer code oplevert en lastiger leest.

Overigens ben ik het met .oisyn eens dat het een beetje onzin is dat een if-statement de state van je programma niet zou moeten kunnen aanpassen. Hoe wou je anders je programma in een andere state brengen op basis van condities?

'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:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:14

Janoz

Moderator Devschuur®

!litemod

Toch vind ik dat Roy-t een punt heeft, maar dan wel wat specifieker. State veranderende expressies is geen probleem, maar state die veranderd halverwege de evaluatie is wel gevaarlijker. In die gevallen moet je het achterwege laten, of moet het duidelijk door de naamgeving van de gebruikte methodes zijn. Je moet de werking van een stuk code simpel kunnen doorgronden zonder elke methode in te stappen. In dit geval is niet te zien dat change de globale variabele i aan gaat passen en ziet de code er dus eigenlijk ook heel onlogisch uit.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Daar ben ik het ook mee eens, maar ongenuanceerde opmerkingen fakkel ik gewoon af ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 21:02

voodooless

Sound is no voodoo!

Ik denk dat dit het wel illustratiever maakt:
Java:
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
public class Blaat {

    private static boolean bounce = false;

    public static final void main(String[] args) {

        if (blaat() && blaat()) {
            System.out.println("blaat");
        } else {
            System.out.println("kaas");
        }
    }

    private static boolean blaat() {
        boolean ret;
        if (!bounce) {
            bounce = true;
            ret = bounce;
        } else {
            ret = false;
        }
        System.out.println("ret: " + ret);
        return ret;
    }
}


8)7

't zal vast wel ergens toepassingen vinden, maar maakt het niet eenvoudig om dergelijke code te lezen of begrijpen.

Do diamonds shine on the dark side of the moon :?

Pagina: 1