These are the general Java style qualities that we expect your programs to have in order to receive full credit. Certainly it is possible to write good code that violates these guidelines, and you may feel free to contact us if you are unclear about or disagree with some of them. But we do expect you to follow these rules (unless there is an error in this document). In most professional work environments you are expected to follow that company's style standards. Learning to carefully obey a style guide, and writing code with a group of other developers where the style is consistent among them, are valuable job skills.
Oracle/Sun's Official Java Coding Conventions are a more comprehensive guide to proper Java programming. The practices outlined on their web site are encouraged for use in CS 106A.
Work in progress.
Increase your indentation by one tab on each brace {
, and decrease it once on each closing brace }
.
Always use {} on control statements. With Java's control statements such as if
and for
, the {}
braces are technically optional if the body of the control statement contains only a single line. Regardless of this, always use the {}
braces. Always :) The reason is that if you come back later to add additional statements to the bodies, you may forget to add braces, and your code will not work as you expect.
// bad
if (beepersPresent())
pickBeeper();
// good
if (beepersPresent()) {
pickBeeper();
}
Place a line break after every {
.
// bad
if (beepersPresent()) { pickBeeper(); }
// good
if (beepersPresent()) {
pickBeeper();
}
Do not place more than one statement on the same line.
// bad
move(); move(); pickBeeper();
// good
move();
move();
pickBeeper();
Avoid lines longer than 80 characters. When you have a long line, break it into two shorter lines.
Place a blank line between methods and between groups of statements.
private void foo() {
...
}
// this blank line here
private void bar() {
...
}
Give methods descriptive names, such as walkToEdge
or grabAllBeepers
. Avoid one-letter names or non-descriptive names, like x
or go
or method1
.
Unless explicitly specified, all methods you write should be private
, not public
.
Name methods with camel-casing likeThis
.
run
As a Concise Summary
As much as possible, avoid having much of your program's functionality directly in run
. Instead, have run
call other methods that perform the functionality. For example, run should not directly call move
. In this way, run
is easy to read and forms a concise summary of the overall behavior of the program.
If you repeat the same code block two or more times, find a way to remove the redundant code so that it appears only once. For example, you can place it into a method that is called from both places.
Each method should perform a single, clear, coherent task. No one method should do too large a share of the overall work. If you have a single method that is very long, break it apart into smaller sub-methods. If you try to describe the method's purpose and find yourself using the word "and" a lot, that probably means the method does too many things and should be split into sub-methods.
It is not useful to make a method that simply calls one other existing method. But it can be useful to have a short method if it wraps another method with some additional control flow.
// bad
private void makeLeftTurn() {
turnLeft();
}
// good
private void safePickup() {
if (beepersPresent()) {
pickBeeper();
}
}
Recursion (which you'll learn about in CS 106B/X) is when methods call themselves. Mutual recursion is where you have two methods that each call the other to form a cycle of calls. In CS 106A assignments, we discourage recursion or mutual recursion, as it is sometimes tricky to understand and debug, even though it can allow for elegant solutions. In many cases, recursion can be replaced with a for
or while
loop instead.
// discouraged (recursion)
public void methodOne() {
if (frontIsClear()) {
move();
methodOne();
}
}
// encouraged
private void moveToWall() {
while (frontIsClear()) {
move();
}
}
// discouraged (mutual recursion)
private void methodOne() {
if (frontIsClear()) {
move();
methodTwo();
}
}
private void methodTwo() {
if (frontIsClear()) {
move();
methodOne();
}
}
if
or else
.
When using if/else
statements, you shouldn't have an if or else branch that is blank. Rephrase your condition to avoid this.
// bad if (frontIsBlocked()) { // do nothing } else { move(); }
// good
if (frontIsClear()) {
move();
}
for
vs. while
Use a for
loop when the number of repetitions is known; use a while
loop when the number of repetitions is unknown.
// for: picks up 5 beepers
for (int i = 0; i < 5; i++) {
pickBeeper();
}
// while: picks up all beepers present
while (beepersPresent()) {
pickBeeper();
}
if/else
Factoring
Move common code out of if/else
statements to reduce repetition.
// bad
if (beepersPresent()) {
turnLeft();
pickBeeper();
move();
turnLeft();
turnLeft();
move();
} else {
move();
move();
turnLeft();
turnLeft();
move();
}
// good
turnLeft();
if (beepersPresent()) {
pickBeeper();
}
move();
turnLeft();
turnLeft();
move();
Except for infinite animation, avoid writing loops that never stop, such as the example below. An infinite loop will cause your program to never stop executing. Replace an infinite loop with a loop that does terminate.
// bad if front is blocked
// but left is clear!
while (leftIsClear()) {
if (frontIsClear()) {
move();
}
}
// good
while (frontIsClear()) {
move();
}
Place a descriptive comment heading on the top of every .java file in your project with your name, section leader, a description of that file's purpose, and a citation of all sources you used to help write your program. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this program or assignment before. It should describe behavior, but not go into great detail about how each piece is implemented.
Place a comment heading on each method of your file. The heading should describe the method's behavior. If your method makes any assumptions (preconditions), mention this in your comments. If it leaves the program in a certain state when it is done (postcondition), mention this as well. Describe the method's behavior, but don't include great detail about how it is implemented. Don't mention language-specific details like it uses an if/else
statement, etc. Here is an example of a good method header comment:
/*
* Jumps Karel over one hurdle of arbitrary height by walking north over it,
* and then back down to his original row.
* Pre: Karel is next to a jumpable hurdle, facing east.
* Post: Karel will be over the hurdle, one column to the right, facing east.
*/
public void jumpHurdle() {
...
}
Inside various methods, if you have sections of code that are lengthy, complex or non-trivial, place small inline comments near these code blocks describing what they are doing.
Do not include obvious or redundant comments about the meaning of statements.
// bad turnLeft(); // turns Karel counter-clockwise move(); // tells Karel to move forward
Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).
You should remove any // TODO:
comments from your programs before turning them in.
It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.
On Assignment 1, you must limit yourself to the Java features shown in the Karel coursereader. There are too many features to list them all, but in general you should match the Java features used in the sample programs in class and in the Karel coursereader and not use any Java features outside of those. In particular, you should not use the following:
You are not allowed to use any variables, such as:
// bad
int steps = 42;
while (steps > 0) {
move();
turnLeft();
steps = steps - 1;
}
These are the 'private' variables that are declared outside of methods. These are just another form of variables and should not be used on Assignment 1.
// bad
public class MyKarel extends Karel {
private int count;
public void run() {
count = 5;
...
}
}
break
, return
and continue
You should not use any of these keywords on Assignment 1, as they are not included in the Karel coursereader.
Java methods are able to accept parameters that affect their behavior. This is not included in the Karel coursereader and is not permitted on Assignment 1.
// bad
public void walk(int numSteps) {
for (int i = 0; i < numSteps; i++) {
move();
}
}
Increase your indentation by one tab on each brace {
, and decrease it once on each closing brace }
.
Always use {} on control statements. With Java's control statements such as if
and for
, the {}
braces are technically optional if the body of the control statement contains only a single line. Regardless of this, always use the {}
braces. Always :) The reason is that if you come back later to add additional statements to the bodies, you may forget to add braces, and your code will not work as you expect.
// bad
if (beepersPresent())
pickBeeper();
// good
if (beepersPresent()) {
pickBeeper();
}
Place a line break after every {
.
// bad
if (beepersPresent()) { pickBeeper(); }
// good
if (beepersPresent()) {
pickBeeper();
}
Do not place more than one statement on the same line.
// bad
move(); move(); pickBeeper();
// good
move();
move();
pickBeeper();
Avoid lines longer than 80 characters. When you have a long line, break it into two shorter lines.
Place a blank line between methods and between groups of statements.
private void foo() {
...
}
// this blank line here
private void bar() {
...
}
Give methods descriptive names, such as walkToEdge
or grabAllBeepers
. Avoid one-letter names or non-descriptive names, like x
or go
or method1
.
Unless explicitly specified, all methods you write should be private
, not public
.
Name methods with camel-casing likeThis
.
run
As a Concise Summary
As much as possible, avoid having much of your program's functionality directly in run
. Instead, have run
call other methods that perform the functionality. For example, run should not directly call move
. In this way, run
is easy to read and forms a concise summary of the overall behavior of the program.
If you repeat the same code block two or more times, find a way to remove the redundant code so that it appears only once. For example, you can place it into a method that is called from both places.
Each method should perform a single, clear, coherent task. No one method should do too large a share of the overall work. If you have a single method that is very long, break it apart into smaller sub-methods. If you try to describe the method's purpose and find yourself using the word "and" a lot, that probably means the method does too many things and should be split into sub-methods.
It is not useful to make a method that simply calls one other existing method. But it can be useful to have a short method if it wraps another method with some additional control flow.
// bad
private void makeLeftTurn() {
turnLeft();
}
// good
private void safePickup() {
if (beepersPresent()) {
pickBeeper();
}
}
Recursion (which you'll learn about in CS 106B/X) is when methods call themselves. Mutual recursion is where you have two methods that each call the other to form a cycle of calls. In CS 106A assignments, we discourage recursion or mutual recursion, as it is sometimes tricky to understand and debug, even though it can allow for elegant solutions. In many cases, recursion can be replaced with a for
or while
loop instead.
// discouraged (recursion)
public void methodOne() {
if (frontIsClear()) {
move();
methodOne();
}
}
// encouraged
private void moveToWall() {
while (frontIsClear()) {
move();
}
}
// discouraged (mutual recursion)
private void methodOne() {
if (frontIsClear()) {
move();
methodTwo();
}
}
private void methodTwo() {
if (frontIsClear()) {
move();
methodOne();
}
}
if
or else
.
When using if/else
statements, you shouldn't have an if or else branch that is blank. Rephrase your condition to avoid this.
// bad if (frontIsBlocked()) { // do nothing } else { move(); }
// good
if (frontIsClear()) {
move();
}
for
vs. while
Use a for
loop when the number of repetitions is known; use a while
loop when the number of repetitions is unknown.
// for: picks up 5 beepers
for (int i = 0; i < 5; i++) {
pickBeeper();
}
// while: picks up all beepers present
while (beepersPresent()) {
pickBeeper();
}
if/else
Factoring
Move common code out of if/else
statements to reduce repetition.
// bad
if (beepersPresent()) {
turnLeft();
pickBeeper();
move();
turnLeft();
turnLeft();
move();
} else {
move();
move();
turnLeft();
turnLeft();
move();
}
// good
turnLeft();
if (beepersPresent()) {
pickBeeper();
}
move();
turnLeft();
turnLeft();
move();
Except for infinite animation, avoid writing loops that never stop, such as the example below. An infinite loop will cause your program to never stop executing. Replace an infinite loop with a loop that does terminate.
// bad if front is blocked
// but left is clear!
while (leftIsClear()) {
if (frontIsClear()) {
move();
}
}
// good
while (frontIsClear()) {
move();
}
break
statement to solve the loop-and-a-half problem. In general, you should avoid other uses of the break
statement and any use of the continue
statement.
// bad use of break
while (true) {
if (frontIsClear()) {
move();
} else {
break;
}
}
// good use of break
while (true) {
int num = readInt("Please enter a number (-1 to quit) ");
if (num == -1) {
break;
}
// process num
...
}
When using if/else
statements, properly choose between various if
and else
patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if
tests.
// bad
if (points >= 90) {
println("You got Gold!");
}
if (points >= 70 && points < 90) {
println("You got Silver!");
}
if (points >= 50 && points < 70) {
println("You got Bronze!");
}
...
// good
if (points >= 90) {
println("You got Gold!");
} else if (points >= 70) {
println("You got Silver!");
} else if (points >= 50) {
println("You got Bronze!");
}
...
Don't test whether a boolean
value is ==
or !=
to true
or false
. It's not necessary! Remember that all booleans (expressions and variables) evaluate to true
or false
on their own.
// bad
if (x == true) {
...
} else if (x != true) {
...
}
// good
if (x) {
...
} else {
...
}
Place a descriptive comment heading on the top of every .java file in your project with your name, section leader, a description of that file's purpose, and a citation of all sources you used to help write your program. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this program or assignment before. It should describe behavior, but not go into great detail about how each piece is implemented.
Place a comment heading on each method of your file. The heading should describe the method's behavior. If your method makes any assumptions (preconditions), mention this in your comments. If it leaves the program in a certain state when it is done (postcondition), mention this as well. Describe the method's behavior, but don't include great detail about how it is implemented. Don't mention language-specific details like it uses an if/else
statement, etc. Here is an example of a good method header comment:
/*
* Jumps Karel over one hurdle of arbitrary height by walking north over it,
* and then back down to his original row.
* Pre: Karel is next to a jumpable hurdle, facing east.
* Post: Karel will be over the hurdle, one column to the right, facing east.
*/
public void jumpHurdle() {
...
}
Inside various methods, if you have sections of code that are lengthy, complex or non-trivial, place small inline comments near these code blocks describing what they are doing.
Do not include obvious or redundant comments about the meaning of statements.
// bad turnLeft(); // turns Karel counter-clockwise move(); // tells Karel to move forward
Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).
You should remove any // TODO:
comments from your programs before turning them in.
It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.
Choose appropriate data types for your variables. If a given variable can store only integers, give it type int
rather than double
.
Declare variables in the narrowest possible scope. For example, if a variable is used only inside a specific if
statement, declare it inside that if
statement rather than at the top of the method or at the top of the file.
Never declare or initialize more than one variable in a single statement.
// bad
int a = 7, b = -43, c = 19;
// good
int a = 7;
int b = -43;
int c = 19;
If a particular constant value is used frequently in your code, declare it as a constant, and always refer to the constant in the rest of your code rather than referring to the corresponding value. Name constants in uppercase with underscores between words LIKE_THIS
.
private static final int DAYS_IN_WEEK = 7;
Java contains a System.exit
method that immediately exits your entire program. You should never call this method in our assignments for any reason. Your program should always exit naturally by reaching the end of your run
function and returning.
Increase your indentation by one tab on each brace {
, and decrease it once on each closing brace }
.
Always use {} on control statements. With Java's control statements such as if
and for
, the {}
braces are technically optional if the body of the control statement contains only a single line. Regardless of this, always use the {}
braces. Always :) The reason is that if you come back later to add additional statements to the bodies, you may forget to add braces, and your code will not work as you expect.
// bad
if (beepersPresent())
pickBeeper();
// good
if (beepersPresent()) {
pickBeeper();
}
Place a line break after every {
.
// bad
if (beepersPresent()) { pickBeeper(); }
// good
if (beepersPresent()) {
pickBeeper();
}
Do not place more than one statement on the same line.
// bad
move(); move(); pickBeeper();
// good
move();
move();
pickBeeper();
Avoid lines longer than 80 characters. When you have a long line, break it into two shorter lines.
Place a blank line between methods and between groups of statements.
private void foo() {
...
}
// this blank line here
private void bar() {
...
}
Give methods descriptive names, such as walkToEdge
or grabAllBeepers
. Avoid one-letter names or non-descriptive names, like x
or go
or method1
.
Unless explicitly specified, all methods you write should be private
, not public
.
Name methods with camel-casing likeThis
.
run
As a Concise Summary
As much as possible, avoid having much of your program's functionality directly in run
. Instead, have run
call other methods that perform the functionality. For example, run should not directly call move
. In this way, run
is easy to read and forms a concise summary of the overall behavior of the program.
If you repeat the same code block two or more times, find a way to remove the redundant code so that it appears only once. For example, you can place it into a method that is called from both places.
Each method should perform a single, clear, coherent task. No one method should do too large a share of the overall work. If you have a single method that is very long, break it apart into smaller sub-methods. If you try to describe the method's purpose and find yourself using the word "and" a lot, that probably means the method does too many things and should be split into sub-methods.
It is not useful to make a method that simply calls one other existing method. But it can be useful to have a short method if it wraps another method with some additional control flow.
// bad
private void makeLeftTurn() {
turnLeft();
}
// good
private void safePickup() {
if (beepersPresent()) {
pickBeeper();
}
}
Recursion (which you'll learn about in CS 106B/X) is when methods call themselves. Mutual recursion is where you have two methods that each call the other to form a cycle of calls. In CS 106A assignments, we discourage recursion or mutual recursion, as it is sometimes tricky to understand and debug, even though it can allow for elegant solutions. In many cases, recursion can be replaced with a for
or while
loop instead.
// discouraged (recursion)
public void methodOne() {
if (frontIsClear()) {
move();
methodOne();
}
}
// encouraged
private void moveToWall() {
while (frontIsClear()) {
move();
}
}
// discouraged (mutual recursion)
private void methodOne() {
if (frontIsClear()) {
move();
methodTwo();
}
}
private void methodTwo() {
if (frontIsClear()) {
move();
methodOne();
}
}
If you have an if/else
statement that returns a boolean value based on a test, just directly return the test's result instead.
// bad
if (score1 == score2) {
return true;
} else {
return false;
}
// good
return score1 == score2;
If you repeat the same code two or more times that is nearly but not entirely the same, try making a helper function that accepts a parameter to represent the differing part.
// bad
foo();
x = 10;
y++;
...
foo();
x = 15;
y++;
// good
helper(10);
helper(15);
...
private void helper(int newX) {
foo();
x = newX;
y++;
}
if
or else
.
When using if/else
statements, you shouldn't have an if or else branch that is blank. Rephrase your condition to avoid this.
// bad if (frontIsBlocked()) { // do nothing } else { move(); }
// good
if (frontIsClear()) {
move();
}
for
vs. while
Use a for
loop when the number of repetitions is known; use a while
loop when the number of repetitions is unknown.
// for: picks up 5 beepers
for (int i = 0; i < 5; i++) {
pickBeeper();
}
// while: picks up all beepers present
while (beepersPresent()) {
pickBeeper();
}
if/else
Factoring
Move common code out of if/else
statements to reduce repetition.
// bad
if (beepersPresent()) {
turnLeft();
pickBeeper();
move();
turnLeft();
turnLeft();
move();
} else {
move();
move();
turnLeft();
turnLeft();
move();
}
// good
turnLeft();
if (beepersPresent()) {
pickBeeper();
}
move();
turnLeft();
turnLeft();
move();
Except for infinite animation, avoid writing loops that never stop, such as the example below. An infinite loop will cause your program to never stop executing. Replace an infinite loop with a loop that does terminate.
// bad if front is blocked
// but left is clear!
while (leftIsClear()) {
if (frontIsClear()) {
move();
}
}
// good
while (frontIsClear()) {
move();
}
break
statement to solve the loop-and-a-half problem. In general, you should avoid other uses of the break
statement and any use of the continue
statement.
// bad use of break
while (true) {
if (frontIsClear()) {
move();
} else {
break;
}
}
// good use of break
while (true) {
int num = readInt("Please enter a number (-1 to quit) ");
if (num == -1) {
break;
}
// process num
...
}
When using if/else
statements, properly choose between various if
and else
patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if
tests.
// bad
if (points >= 90) {
println("You got Gold!");
}
if (points >= 70 && points < 90) {
println("You got Silver!");
}
if (points >= 50 && points < 70) {
println("You got Bronze!");
}
...
// good
if (points >= 90) {
println("You got Gold!");
} else if (points >= 70) {
println("You got Silver!");
} else if (points >= 50) {
println("You got Bronze!");
}
...
Don't test whether a boolean
value is ==
or !=
to true
or false
. It's not necessary! Remember that all booleans (expressions and variables) evaluate to true
or false
on their own.
// bad
if (x == true) {
...
} else if (x != true) {
...
}
// good
if (x) {
...
} else {
...
}
Place a descriptive comment heading on the top of every .java file in your project with your name, section leader, a description of that file's purpose, and a citation of all sources you used to help write your program. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this program or assignment before. It should describe behavior, but not go into great detail about how each piece is implemented.
Place a comment heading on each method of your file. The heading should describe the method's behavior. If your method makes any assumptions (preconditions), mention this in your comments. If it leaves the program in a certain state when it is done (postcondition), mention this as well. Describe the method's behavior, but don't include great detail about how it is implemented. Don't mention language-specific details like it uses an if/else
statement, etc. Here is an example of a good method header comment:
/*
* Jumps Karel over one hurdle of arbitrary height by walking north over it,
* and then back down to his original row.
* Pre: Karel is next to a jumpable hurdle, facing east.
* Post: Karel will be over the hurdle, one column to the right, facing east.
*/
public void jumpHurdle() {
...
}
Inside various methods, if you have sections of code that are lengthy, complex or non-trivial, place small inline comments near these code blocks describing what they are doing.
Do not include obvious or redundant comments about the meaning of statements.
// bad turnLeft(); // turns Karel counter-clockwise move(); // tells Karel to move forward
Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).
You should remove any // TODO:
comments from your programs before turning them in.
It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.
Choose appropriate data types for your variables. If a given variable can store only integers, give it type int
rather than double
.
Declare variables in the narrowest possible scope. For example, if a variable is used only inside a specific if
statement, declare it inside that if
statement rather than at the top of the method or at the top of the file.
Never declare or initialize more than one variable in a single statement.
// bad
int a = 7, b = -43, c = 19;
// good
int a = 7;
int b = -43;
int c = 19;
If a particular constant value is used frequently in your code, declare it as a constant, and always refer to the constant in the rest of your code rather than referring to the corresponding value. Name constants in uppercase with underscores between words LIKE_THIS
.
private static final int DAYS_IN_WEEK = 7;
If you are calling a method and using its result multiple times, save that result in a variable rather than having to call the method multiple times.
// bad
if (getElementAt(x, y) != null) {
remove(getElementAt(x, y));
}
// good
GObject obj = getElementAt(x, y);
if (obj != null) {
remove(obj);
}
Don't ever catch an exception with an empty catch
block.
// bad
try {
foo();
bar();
} catch (NullPointerException e) {}
Don't use try/catch
to cover up an error that your program is generating. Only use it for unavoidable program errors such as file errors. If your program is generating an error, debug and sidestep the error to prevent it from happening instead.
// bad try { myFunctionThatCrashesForSomeReason(); } catch (IndexOutOfBoundsException e) { //no crash now... }
catch(Exception e)
Don't ever catch (Exception e)
unless told explicitly to do so, because this will catch a huge number of errors and will suppress important system error messages. You should instead catch a more specific subcategory of exceptions such as IOException
or FileNotFoundException
.
// bad
try {
foo();
bar();
} catch (Exception e) {}
Java contains a System.exit
method that immediately exits your entire program. You should never call this method in our assignments for any reason. Your program should always exit naturally by reaching the end of your run
function and returning.
Increase your indentation by one tab on each brace {
, and decrease it once on each closing brace }
.
Always use {} on control statements. With Java's control statements such as if
and for
, the {}
braces are technically optional if the body of the control statement contains only a single line. Regardless of this, always use the {}
braces. Always :) The reason is that if you come back later to add additional statements to the bodies, you may forget to add braces, and your code will not work as you expect.
// bad
if (beepersPresent())
pickBeeper();
// good
if (beepersPresent()) {
pickBeeper();
}
Place a line break after every {
.
// bad
if (beepersPresent()) { pickBeeper(); }
// good
if (beepersPresent()) {
pickBeeper();
}
Do not place more than one statement on the same line.
// bad
move(); move(); pickBeeper();
// good
move();
move();
pickBeeper();
Avoid lines longer than 80 characters. When you have a long line, break it into two shorter lines.
Place a blank line between methods and between groups of statements.
private void foo() {
...
}
// this blank line here
private void bar() {
...
}
Give methods descriptive names, such as walkToEdge
or grabAllBeepers
. Avoid one-letter names or non-descriptive names, like x
or go
or method1
.
Unless explicitly specified, all methods you write should be private
, not public
.
Name methods with camel-casing likeThis
.
run
As a Concise Summary
As much as possible, avoid having much of your program's functionality directly in run
. Instead, have run
call other methods that perform the functionality. For example, run should not directly call move
. In this way, run
is easy to read and forms a concise summary of the overall behavior of the program.
If you repeat the same code block two or more times, find a way to remove the redundant code so that it appears only once. For example, you can place it into a method that is called from both places.
Each method should perform a single, clear, coherent task. No one method should do too large a share of the overall work. If you have a single method that is very long, break it apart into smaller sub-methods. If you try to describe the method's purpose and find yourself using the word "and" a lot, that probably means the method does too many things and should be split into sub-methods.
It is not useful to make a method that simply calls one other existing method. But it can be useful to have a short method if it wraps another method with some additional control flow.
// bad
private void makeLeftTurn() {
turnLeft();
}
// good
private void safePickup() {
if (beepersPresent()) {
pickBeeper();
}
}
Recursion (which you'll learn about in CS 106B/X) is when methods call themselves. Mutual recursion is where you have two methods that each call the other to form a cycle of calls. In CS 106A assignments, we discourage recursion or mutual recursion, as it is sometimes tricky to understand and debug, even though it can allow for elegant solutions. In many cases, recursion can be replaced with a for
or while
loop instead.
// discouraged (recursion)
public void methodOne() {
if (frontIsClear()) {
move();
methodOne();
}
}
// encouraged
private void moveToWall() {
while (frontIsClear()) {
move();
}
}
// discouraged (mutual recursion)
private void methodOne() {
if (frontIsClear()) {
move();
methodTwo();
}
}
private void methodTwo() {
if (frontIsClear()) {
move();
methodOne();
}
}
If you have an if/else
statement that returns a boolean value based on a test, just directly return the test's result instead.
// bad
if (score1 == score2) {
return true;
} else {
return false;
}
// good
return score1 == score2;
If you repeat the same code two or more times that is nearly but not entirely the same, try making a helper function that accepts a parameter to represent the differing part.
// bad
foo();
x = 10;
y++;
...
foo();
x = 15;
y++;
// good
helper(10);
helper(15);
...
private void helper(int newX) {
foo();
x = newX;
y++;
}
if
or else
.
When using if/else
statements, you shouldn't have an if or else branch that is blank. Rephrase your condition to avoid this.
// bad if (frontIsBlocked()) { // do nothing } else { move(); }
// good
if (frontIsClear()) {
move();
}
for
vs. while
Use a for
loop when the number of repetitions is known; use a while
loop when the number of repetitions is unknown.
// for: picks up 5 beepers
for (int i = 0; i < 5; i++) {
pickBeeper();
}
// while: picks up all beepers present
while (beepersPresent()) {
pickBeeper();
}
if/else
Factoring
Move common code out of if/else
statements to reduce repetition.
// bad
if (beepersPresent()) {
turnLeft();
pickBeeper();
move();
turnLeft();
turnLeft();
move();
} else {
move();
move();
turnLeft();
turnLeft();
move();
}
// good
turnLeft();
if (beepersPresent()) {
pickBeeper();
}
move();
turnLeft();
turnLeft();
move();
Except for infinite animation, avoid writing loops that never stop, such as the example below. An infinite loop will cause your program to never stop executing. Replace an infinite loop with a loop that does terminate.
// bad if front is blocked
// but left is clear!
while (leftIsClear()) {
if (frontIsClear()) {
move();
}
}
// good
while (frontIsClear()) {
move();
}
break
statement to solve the loop-and-a-half problem. In general, you should avoid other uses of the break
statement and any use of the continue
statement.
// bad use of break
while (true) {
if (frontIsClear()) {
move();
} else {
break;
}
}
// good use of break
while (true) {
int num = readInt("Please enter a number (-1 to quit) ");
if (num == -1) {
break;
}
// process num
...
}
When using if/else
statements, properly choose between various if
and else
patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if
tests.
// bad
if (points >= 90) {
println("You got Gold!");
}
if (points >= 70 && points < 90) {
println("You got Silver!");
}
if (points >= 50 && points < 70) {
println("You got Bronze!");
}
...
// good
if (points >= 90) {
println("You got Gold!");
} else if (points >= 70) {
println("You got Silver!");
} else if (points >= 50) {
println("You got Bronze!");
}
...
Don't test whether a boolean
value is ==
or !=
to true
or false
. It's not necessary! Remember that all booleans (expressions and variables) evaluate to true
or false
on their own.
// bad
if (x == true) {
...
} else if (x != true) {
...
}
// good
if (x) {
...
} else {
...
}
Place a descriptive comment heading on the top of every .java file in your project with your name, section leader, a description of that file's purpose, and a citation of all sources you used to help write your program. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this program or assignment before. It should describe behavior, but not go into great detail about how each piece is implemented.
Place a comment heading on each method of your file. The heading should describe the method's behavior. If your method makes any assumptions (preconditions), mention this in your comments. If it leaves the program in a certain state when it is done (postcondition), mention this as well. Describe the method's behavior, but don't include great detail about how it is implemented. Don't mention language-specific details like it uses an if/else
statement, etc. Here is an example of a good method header comment:
/*
* Jumps Karel over one hurdle of arbitrary height by walking north over it,
* and then back down to his original row.
* Pre: Karel is next to a jumpable hurdle, facing east.
* Post: Karel will be over the hurdle, one column to the right, facing east.
*/
public void jumpHurdle() {
...
}
Inside various methods, if you have sections of code that are lengthy, complex or non-trivial, place small inline comments near these code blocks describing what they are doing.
Do not include obvious or redundant comments about the meaning of statements.
// bad turnLeft(); // turns Karel counter-clockwise move(); // tells Karel to move forward
Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).
You should remove any // TODO:
comments from your programs before turning them in.
It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.
Choose appropriate data types for your variables. If a given variable can store only integers, give it type int
rather than double
.
Declare variables in the narrowest possible scope. For example, if a variable is used only inside a specific if
statement, declare it inside that if
statement rather than at the top of the method or at the top of the file.
Never declare or initialize more than one variable in a single statement.
// bad
int a = 7, b = -43, c = 19;
// good
int a = 7;
int b = -43;
int c = 19;
If a particular constant value is used frequently in your code, declare it as a constant, and always refer to the constant in the rest of your code rather than referring to the corresponding value. Name constants in uppercase with underscores between words LIKE_THIS
.
private static final int DAYS_IN_WEEK = 7;
If you are calling a method and using its result multiple times, save that result in a variable rather than having to call the method multiple times.
// bad
if (getElementAt(x, y) != null) {
remove(getElementAt(x, y));
}
// good
GObject obj = getElementAt(x, y);
if (obj != null) {
remove(obj);
}
Use instance variables only when they are required to implement certain functionality, or if it makes sense for that variable to persist outside of any given method. Only use them to store important data that is relevant to the whole program.
Don't ever catch an exception with an empty catch
block.
// bad
try {
foo();
bar();
} catch (NullPointerException e) {}
Don't use try/catch
to cover up an error that your program is generating. Only use it for unavoidable program errors such as file errors. If your program is generating an error, debug and sidestep the error to prevent it from happening instead.
// bad try { myFunctionThatCrashesForSomeReason(); } catch (IndexOutOfBoundsException e) { //no crash now... }
catch(Exception e)
Don't ever catch (Exception e)
unless told explicitly to do so, because this will catch a huge number of errors and will suppress important system error messages. You should instead catch a more specific subcategory of exceptions such as IOException
or FileNotFoundException
.
// bad
try {
foo();
bar();
} catch (Exception e) {}
Java contains a System.exit
method that immediately exits your entire program. You should never call this method in our assignments for any reason. Your program should always exit naturally by reaching the end of your run
function and returning.
Increase your indentation by one tab on each brace {
, and decrease it once on each closing brace }
.
Always use {} on control statements. With Java's control statements such as if
and for
, the {}
braces are technically optional if the body of the control statement contains only a single line. Regardless of this, always use the {}
braces. Always :) The reason is that if you come back later to add additional statements to the bodies, you may forget to add braces, and your code will not work as you expect.
// bad
if (beepersPresent())
pickBeeper();
// good
if (beepersPresent()) {
pickBeeper();
}
Place a line break after every {
.
// bad
if (beepersPresent()) { pickBeeper(); }
// good
if (beepersPresent()) {
pickBeeper();
}
Do not place more than one statement on the same line.
// bad
move(); move(); pickBeeper();
// good
move();
move();
pickBeeper();
Avoid lines longer than 80 characters. When you have a long line, break it into two shorter lines.
Place a blank line between methods and between groups of statements.
private void foo() {
...
}
// this blank line here
private void bar() {
...
}
Give methods descriptive names, such as walkToEdge
or grabAllBeepers
. Avoid one-letter names or non-descriptive names, like x
or go
or method1
.
Unless explicitly specified, all methods you write should be private
, not public
.
Name methods with camel-casing likeThis
.
run
As a Concise Summary
As much as possible, avoid having much of your program's functionality directly in run
. Instead, have run
call other methods that perform the functionality. For example, run should not directly call move
. In this way, run
is easy to read and forms a concise summary of the overall behavior of the program.
If you repeat the same code block two or more times, find a way to remove the redundant code so that it appears only once. For example, you can place it into a method that is called from both places.
Each method should perform a single, clear, coherent task. No one method should do too large a share of the overall work. If you have a single method that is very long, break it apart into smaller sub-methods. If you try to describe the method's purpose and find yourself using the word "and" a lot, that probably means the method does too many things and should be split into sub-methods.
It is not useful to make a method that simply calls one other existing method. But it can be useful to have a short method if it wraps another method with some additional control flow.
// bad
private void makeLeftTurn() {
turnLeft();
}
// good
private void safePickup() {
if (beepersPresent()) {
pickBeeper();
}
}
Recursion (which you'll learn about in CS 106B/X) is when methods call themselves. Mutual recursion is where you have two methods that each call the other to form a cycle of calls. In CS 106A assignments, we discourage recursion or mutual recursion, as it is sometimes tricky to understand and debug, even though it can allow for elegant solutions. In many cases, recursion can be replaced with a for
or while
loop instead.
// discouraged (recursion)
public void methodOne() {
if (frontIsClear()) {
move();
methodOne();
}
}
// encouraged
private void moveToWall() {
while (frontIsClear()) {
move();
}
}
// discouraged (mutual recursion)
private void methodOne() {
if (frontIsClear()) {
move();
methodTwo();
}
}
private void methodTwo() {
if (frontIsClear()) {
move();
methodOne();
}
}
If you have an if/else
statement that returns a boolean value based on a test, just directly return the test's result instead.
// bad
if (score1 == score2) {
return true;
} else {
return false;
}
// good
return score1 == score2;
If you repeat the same code two or more times that is nearly but not entirely the same, try making a helper function that accepts a parameter to represent the differing part.
// bad
foo();
x = 10;
y++;
...
foo();
x = 15;
y++;
// good
helper(10);
helper(15);
...
private void helper(int newX) {
foo();
x = newX;
y++;
}
if
or else
.
When using if/else
statements, you shouldn't have an if or else branch that is blank. Rephrase your condition to avoid this.
// bad if (frontIsBlocked()) { // do nothing } else { move(); }
// good
if (frontIsClear()) {
move();
}
for
vs. while
Use a for
loop when the number of repetitions is known; use a while
loop when the number of repetitions is unknown.
// for: picks up 5 beepers
for (int i = 0; i < 5; i++) {
pickBeeper();
}
// while: picks up all beepers present
while (beepersPresent()) {
pickBeeper();
}
if/else
Factoring
Move common code out of if/else
statements to reduce repetition.
// bad
if (beepersPresent()) {
turnLeft();
pickBeeper();
move();
turnLeft();
turnLeft();
move();
} else {
move();
move();
turnLeft();
turnLeft();
move();
}
// good
turnLeft();
if (beepersPresent()) {
pickBeeper();
}
move();
turnLeft();
turnLeft();
move();
Except for infinite animation, avoid writing loops that never stop, such as the example below. An infinite loop will cause your program to never stop executing. Replace an infinite loop with a loop that does terminate.
// bad if front is blocked
// but left is clear!
while (leftIsClear()) {
if (frontIsClear()) {
move();
}
}
// good
while (frontIsClear()) {
move();
}
break
statement to solve the loop-and-a-half problem. In general, you should avoid other uses of the break
statement and any use of the continue
statement.
// bad use of break
while (true) {
if (frontIsClear()) {
move();
} else {
break;
}
}
// good use of break
while (true) {
int num = readInt("Please enter a number (-1 to quit) ");
if (num == -1) {
break;
}
// process num
...
}
When using if/else
statements, properly choose between various if
and else
patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if
tests.
// bad
if (points >= 90) {
println("You got Gold!");
}
if (points >= 70 && points < 90) {
println("You got Silver!");
}
if (points >= 50 && points < 70) {
println("You got Bronze!");
}
...
// good
if (points >= 90) {
println("You got Gold!");
} else if (points >= 70) {
println("You got Silver!");
} else if (points >= 50) {
println("You got Bronze!");
}
...
Don't test whether a boolean
value is ==
or !=
to true
or false
. It's not necessary! Remember that all booleans (expressions and variables) evaluate to true
or false
on their own.
// bad
if (x == true) {
...
} else if (x != true) {
...
}
// good
if (x) {
...
} else {
...
}
Place a descriptive comment heading on the top of every .java file in your project with your name, section leader, a description of that file's purpose, and a citation of all sources you used to help write your program. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this program or assignment before. It should describe behavior, but not go into great detail about how each piece is implemented.
Place a comment heading on each method of your file. The heading should describe the method's behavior. If your method makes any assumptions (preconditions), mention this in your comments. If it leaves the program in a certain state when it is done (postcondition), mention this as well. Describe the method's behavior, but don't include great detail about how it is implemented. Don't mention language-specific details like it uses an if/else
statement, etc. Here is an example of a good method header comment:
/*
* Jumps Karel over one hurdle of arbitrary height by walking north over it,
* and then back down to his original row.
* Pre: Karel is next to a jumpable hurdle, facing east.
* Post: Karel will be over the hurdle, one column to the right, facing east.
*/
public void jumpHurdle() {
...
}
Inside various methods, if you have sections of code that are lengthy, complex or non-trivial, place small inline comments near these code blocks describing what they are doing.
Do not include obvious or redundant comments about the meaning of statements.
// bad turnLeft(); // turns Karel counter-clockwise move(); // tells Karel to move forward
Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).
You should remove any // TODO:
comments from your programs before turning them in.
It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.
Choose appropriate data types for your variables. If a given variable can store only integers, give it type int
rather than double
.
Declare variables in the narrowest possible scope. For example, if a variable is used only inside a specific if
statement, declare it inside that if
statement rather than at the top of the method or at the top of the file.
Never declare or initialize more than one variable in a single statement.
// bad
int a = 7, b = -43, c = 19;
// good
int a = 7;
int b = -43;
int c = 19;
If a particular constant value is used frequently in your code, declare it as a constant, and always refer to the constant in the rest of your code rather than referring to the corresponding value. Name constants in uppercase with underscores between words LIKE_THIS
.
private static final int DAYS_IN_WEEK = 7;
If you are calling a method and using its result multiple times, save that result in a variable rather than having to call the method multiple times.
// bad
if (getElementAt(x, y) != null) {
remove(getElementAt(x, y));
}
// good
GObject obj = getElementAt(x, y);
if (obj != null) {
remove(obj);
}
Use instance variables only when they are required to implement certain functionality, or if it makes sense for that variable to persist outside of any given method. Only use them to store important data that is relevant to the whole program.
Don't ever catch an exception with an empty catch
block.
// bad
try {
foo();
bar();
} catch (NullPointerException e) {}
Don't use try/catch
to cover up an error that your program is generating. Only use it for unavoidable program errors such as file errors. If your program is generating an error, debug and sidestep the error to prevent it from happening instead.
// bad try { myFunctionThatCrashesForSomeReason(); } catch (IndexOutOfBoundsException e) { //no crash now... }
catch(Exception e)
Don't ever catch (Exception e)
unless told explicitly to do so, because this will catch a huge number of errors and will suppress important system error messages. You should instead catch a more specific subcategory of exceptions such as IOException
or FileNotFoundException
.
// bad
try {
foo();
bar();
} catch (Exception e) {}
Properly encapsulate your objects by making any instance variables in your class private
.
public class Player { private int numberOfLives; ... }
Use instance variables only when they are required to implement certain functionality, or if it makes sense for that variable to persist outside of any given method. Don't use them to store temporary values used in only a single call to one method, for instance; use them to store important data of your objects.
Don't initialize instance variables where they are declared; instead, initialize them in the constructor.
public class Player {private int numberOfLives = 10;private int numberOfLives; public Player() { numberOfLives = 10; } }
If you don't need to do anything to initialize your object, just omit the constructor.
public class Player { ...public Player() {}}
If you add a method to a class that is not part of the homework spec, make it private
so that other external code cannot call it.
public class Player { ... private double computeScoreHelper() { ... } }
A static variable in a class is a single occurrence shared by that class and all of its objects. An instance variable is one that each object has its own copy of. When designing your class, any data that should be unique to each object should be an instance variable. This still holds even if the assignment only happens to construct one instance of your class.
public class Player {private static int numberOfLives;// all players share one life count (bad) private int numberOfLives; // each player has their own life count (good) public Player() { numberOfLives = 10; } }
Java contains a System.exit
method that immediately exits your entire program. You should never call this method in our assignments for any reason. Your program should always exit naturally by reaching the end of your run
function and returning.