---
tags: Documents-Summer21
---
# Java Good Coding Practices (Level Two)
:::info
This guide is currently at **Level Two** and contains additional guidelines for managing Exceptions in Java.
:::
## Introduction
This document is the CS18 'good' coding practices guide. Writing code that follows these practices will serve you well beyond CS18, because when your code is well structured and well organized, it is easier to read, debug, test, optimize, etc.
Please read this guide carefully. In addition to functionality, your assignments will be graded on how well you abide by these good practices, so this guide should be a valuable tool to you while coding.
Finally, the examples in this document are written in Java, but they apply equally to Scala and all languages which support the features mentioned. These are language-independent good
coding practices; practices you should embrace in all your future programming endeavors.
## Bad Practices
The following is a compilation of practices to **avoid** when writing code in CS18 (and beyond).
#### Repeated Code
It is bad practice to repeat code. Instead, try to abstract out repeated code to a helper method, an abstract class, or a utility class so that it can be shared.
#### Overly Complicated Logic
You should always aim to avoid using overly complicated logic in your code. *The simplest solution is usually the best!* If you find yourself using convoluted logic in an assignment during CS18, it may be best to take a step back and reconsider your approach. If you must hand in complicated code, be sure to add clear and concise comments, and, as always, give your variables meaningful names.
#### Overuse of `public` modifier
It is bad practice to declare member variables public, as they can then be accessed/modified by other code. Instead, they should be declared `private` (or `protected`), and accessed via getter and setter methods.
#### Use of `instanceof`
When programming, you should (almost) always know the type of your data, so needing to use `instanceof` implies a bad design and should make you rethink your class hierarchy. An exception to this rule is the use of `instanceof` when overriding the equals method.
#### Boolean Logic
* **A variable should never be directly compared to a boolean**, as doing so is redundant. For example, this condition
```java
if (x == true) {
...
}
```
evaluates to `true` if `x` is `true` and `false` if `x` is `false`, meaning the comparison is redundant. The above statement should instead be written as
```java
if (x) {
...
}
```
* **An `if/else` statement should never set a variable's value to a boolean**, as the variable can be set to the value of the predicate instead. For example, this statement
```java
boolean myBool;
if (x == y) {
myBool = true;
} else {
myBool = false;
}
```
sets `myBool` to `true` if `x == y` and `false` otherwise, so it should instead be written as
```java
boolean myBool = (x == y);
```
* **It is bad practice to leave a section of an `if/else` statement empty**. For example:
```java
if (x == y) {
} else {
myFunction();
}
```
The above statement should instead be written as:
```java
if (x != y) {
myFunction();
}
```
#### Exceptions
The following good coding practices pertain to throwing and handling exceptions.
* **You should never catch an unchecked exception**. Unchecked exceptions, like `ArrayOutOfBoundsException` and `NullPointerException`, which extend `RunTimeException`, represent things that should never happen (accessing the −1st item in an array, getting the first item of an empty collection, etc.). When your program encounters an unchecked exception, it exits ungracefully, dumping error information to the console and confusing your users. If your program is throwing an unchecked exception, don’t catch it: fix your code! Instead of writing this:
```java
try {
...
} catch (NullPointerException npe) {
...
}
```
you should aim to write code so that it does not throw a `NullPointerException`.
* **You should never catch `Exception`**. The `Exception class` is the root of the exception hierarchy—the class from which all exceptions (including `RunTimeException`) inherit. You should never catch `Exception`, as it is unchecked (it is a superclass of the class of all unchecked exceptions!). Regardless, you should always catch the most specific exception possible. If you catch only very general exceptions, catastrophic behavior can occur without explanation, making your code difficult to debug. Instead of writing this:
```java
try {
...
} catch (Exception e) {
...
}
```
you should catch and handle the specific checked exceptions that you are expecting to encounter separately, like this:
```java
try {
...
} catch (FileNotFoundException fnfe) {
...
} catch (IOException ioe) {
...
}
```
* **You shouldn't write useless `try/catch` blocks**. Instead, your `try/catch` blocks should do some useful work, like printing out an informative error message or handling the error. Printing out a stack trace is generally not all that useful to a user. Also, avoid catching an exception just to throw it again. For example:
```java
try {
...
} catch (FileNotFoundException fnfe) {
...
throw new FileNotFoundException();
}
```
You should either not catch the `FileNotFoundException` in the first palce or handle it gracefully.
:::info
Printing a stack trace or catching and re-throwing an exception may be helpful while debugging but should be removed before making code available to other users (or graders).
:::
## Good Practices
This list is a compilation of good practices when writing code in CS18 (and beyond).
#### Be lavish with interfaces
An interface is a set of behaviors. Interfaces are not essential to a program’s functionality, but they are useful (perhaps even essential) to debugging because they create requirements for programmers. As a rule of thumb, you should be lavish with interfaces. More interfaces make your code more readable, more extensible, and more easily testable. When in doubt, use an interface!
#### Code is written once but read many times
Because of this, you should put a huge emphasis on the readibility of your code. In CS18, your code will be read by project partners, graders, and even your future self. If you pursue a career in software development, your code may be read by dozens of coworkers over a long period of time. It is critically important that others be able to understand your thought process easily by reading the code that you write. You should follow the following guidelines to facilitate this.
#### Use descriptive variable names
Your variable names should be as informative as possible. The following are examples of poorly-named variables:
```java
int p;
String var;
int[] arr;
```
These names do not help the reader understand what the variables represent. For example, these could be renamed:
```java
int numberOfStudents;
String currentStudentName;
int[] gradeArray;
```
#### Use constants and avoid magic numbers
Sometimes you will need to use constants in your code (maybe for initializing arrays of a set size). Referencing a number directly in code is bad, and we call that number a *magic number*. For example, this is bad:
```java
int[] array1 = new int[10];
int[] array2 = new int[10];
int[] array3 = new int[10];
```
In this example,`10` is a *magic number* because it is referenced directly in the code. Instead, constants should be declared as `private static final` variables at the top of a class in all uppercase snake case rather than hardcoded throughout.
```java
private static final ARRAY_SIZE;
...
int[] array1 = new int[ARRAY_SIZE];
int[] array2 = new int[ARRAY_SIZE];
int[] array3 = new int[ARRAY_SIZE];
```
#### Use brackets
While your Java code may well compile without brackets, you should **always** use them when writing `if` statements, `for` loops, and `while` loops. For example, this is bad:
```java
for (int x = 0; x < 10; x++)
if (x == y)
return "x equals y, yay!";
```
and should be rewritten as:
```java
for (int x = 0; x < 10; x++) {
if (x == y) {
return "x equals y, yay!";
}
}
```
## Style
It is good coding practice to abide by the conventions of the language in which you are programming. These conventions are usually outlined in a *style guide*. The current CS18 Java style guide can be found [here](https://hackmd.io/@cs18-spring-2021/H1tqkCU_u). You should read these style guide to better understand the conventions and expectations for Java and Scala code in CS18.
---
*Please let us know if you find any mistakes, inconsistencies, or confusing language in this or any other CS18 document by filling out the (mostly) [anonymous feedback form](https://cs.brown.edu/courses/cs018/feedback)!*