Some coding issues Statement groups, semi-colons and ifs
If you can keep your head when all about you are losing theirs, it's just possible you haven't grasped the situation.
Some coding issues... Be careful with { statement grouping brackets } and semi-colons; Every statement and declaration ends with a semi-colon; ; In Java, writing nothing also counts as a statement; This line; is a sequence;;; of six; “statements”;
An if-construct starts with an if, then a (condition in round brackets ), then a statement; or {group of statements} Optionally, an if-construct may continue with an else, followed by a statement; or {group of statements} In Java:
An if-construct starts with an if, then a (condition in round brackets ), then a {group of statements} Optionally, an if-construct may continue with an else, followed by a {group of statements} { } However, we recommend always to use a {group of statements} for the statement parts … i.e. {} ; … even if the {group of statements} contains only a single statement;
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0); { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } What’s wrong here?
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0); { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } This is a complete if-construct with an empty statement, . Code layout is necessary to aid readability by reflecting code structure – unfortunately, the above layout reflects only our intention … and not the actual structure written!
This is a complete if-construct with an empty statement, . If the condition is true (i.e. the notebook is empty), an empty statement is executed (which does nothing). So, nothing is done, regardless of whether the condition is true or not! /** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0); { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } }
Here is a statement-group … it has only one statement (which is OK and happens quite a lot). It is executed after that (useless) if-construct, regardless of whether the condition was true or not!
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0); { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } Here is an else-statement-group that is part of no if-construct. This is illegal and will not compile!
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0); { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } This is a complete if-construct with an empty statement, . Get rid of the semi-colon …
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0) { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } We now have a legal if-construct. The first statement-group is executed if the condition is true. The second statement-group is executed if the condition is false. We now have a legal if-construct. The first statement-group is executed if the condition is true. The second statement-group is executed if the condition is false.
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() = 0) { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } This is an (illegal) assignment statement, . Be careful not to confuse == (which is the test-for-equality symbol) with = (which is the assignment symbol). The above code has an assignment statement where it should have a condition. This is illegal.
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0) { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } Back to our legal if-construct. There is another way to express the same logic …
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0) { System.out.println("Notebook is empty"); return; } System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } This if-construct has no else-part and is legal. If the condition is true, the statement-group is executed … and this contains a return statement (which immediately exits the method). If the condition is false, the if-construct is finished and the statements following it are executed.
However, this is a little clever … on the whole, we prefer expressing the alternatives explicitly … /** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0) { System.out.println("Notebook is empty"); return; } System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); }
/** * Print out notebook info (number of entries). */ public void showStatus() { if(notes.size() == 0) { System.out.println("Notebook is empty"); } else { System.out.print("Notebook holds "); System.out.println(notes.size() + " notes"); } } … as we had before. … as we had before.
/** * Store a new note in the notebook. If the * notebook is full, save it and start a new one. */ public void addNote(String note) { if(notes.size() == 100) notes.save(); // starting new notebook notes = new ArrayList (); notes.add(note); } What’s wrong here?
This is a complete if-construct with a single statement, . /** * Store a new note in the notebook. If the * notebook is full, save it and start a new one. */ public void addNote(String note) { if(notes.size() == 100) notes.save(); // starting new notebook notes = new ArrayList (); notes.add(note); } Oh dear, we forgot the curly brackets … … correct layout for the above logic (which we don’t want) would be:
This is a complete if-construct with a single statement, . /** * Store a new note in the notebook. If the * notebook is full, save it and start a new one. */ public void addNote(String note) { if(notes.size() == 100) notes.save(); // starting new notebook notes = new ArrayList (); notes.add(note); } In the above, if the condition is true, save the notes. Whether the condition is true or false, start a new notebook …
This is a complete if-construct with a single statement, . /** * Store a new note in the notebook. If the * notebook is full, save it and start a new one. */ public void addNote(String note) { if(notes.size() == 100) notes.save(); // starting new notebook notes = new ArrayList (); notes.add(note); } Let’s try again … this time, we add in the curly brackets so that the logical structure matches the layout:
This is a complete if-construct with a statement-group, . /** * Store a new note in the notebook. If the * notebook is full, save it and start a new one. */ public void addNote(String note) { if(notes.size() == 100) { notes.save(); // starting new notebook notes = new ArrayList (); } notes.add(note); } Now, the logical structure of the if-construct matches its layout. Now, the logical structure of the if-construct matches its layout.
Always write your code as if the guy who ends up maintaining it will be a violent psychopath who knows where you live … Be careful with { statement grouping brackets } and semi-colons; Always use { statement-groups } for the actions dependent upon the ( condition ) in an if-construct.
Debugging Using the BlueJ debugger (section 3.12) Concepts Only when all else fails – i.e. not as a first resort! First resort: read your code! Why should it work … not why doesn’t it work?!! Explain to a friend. First resort: read your code! Why should it work … not why doesn’t it work?!! Explain to a friend.