Declaring local variables without using them immediately may unnecessarily increase their scope. This decreases legibility, and increases the likelihood of error.
There are two common cases where a local variable is assigned some default initial
value (typically null, 0, false,
or an empty String
):
try
block, and
are thus declared and initialized just before the try
block (in modern code
using try-with-resources, this is now relatively rare)Here, input
and output
are examples of local variables
being initialized to null
, since they need to be visible in both
the try
and finally
blocks.
As well, line
is an example of a loop variable declared and
initialized outside the loop.
Note that this example uses JDK 6, simply to illustrate the point.
In JDK 7, try-with-resources
would be used to automatically close streams, and the issue
of stream references being initialized to null
would not occur.
import java.io.*; /** JDK 6 or before. */ public final class ReadWriteTextFile { /** * Fetch the entire contents of a text file, and return it in a String. * This style of implementation does not throw Exceptions to the caller. * * @param file is a file which already exists and can be read. */ static public String getContents(File file) { //...checks on aFile are elided StringBuilder contents = new StringBuilder(); try { //use buffering, reading one line at a time //FileReader always assumes default encoding is OK! BufferedReader input = new BufferedReader(new FileReader(file)); try { String line = null; //not declared within while loop /* * readLine is a bit quirky : * it returns the content of a line MINUS the newline. * it returns null only for the END of the stream. * it returns an empty String if two newlines appear in a row. */ while (( line = input.readLine()) != null){ contents.append(line); contents.append(System.getProperty("line.separator")); } } finally { input.close(); } } catch (IOException ex){ ex.printStackTrace(); } return contents.toString(); } /** * Change the contents of text file in its entirety, overwriting any * existing text. * * This style of implementation throws all exceptions to the caller. * * @param file is an existing file which can be written to. * @throws IllegalArgumentException if param does not comply. * @throws FileNotFoundException if the file does not exist. * @throws IOException if problem encountered during write. */ static public void setContents( File file, String contents ) throws FileNotFoundException, IOException { if (file == null) { throw new IllegalArgumentException("File should not be null."); } if (!file.exists()) { throw new FileNotFoundException ("File does not exist: " + file); } if (!file.isFile()) { throw new IllegalArgumentException("Should not be a directory: " + file); } if (!file.canWrite()) { throw new IllegalArgumentException("File cannot be written: " + file); } //use buffering Writer output = new BufferedWriter(new FileWriter(file)); try { //FileWriter always assumes default encoding is OK! output.write( contents ); } finally { output.close(); } } /** Simple test harness. */ public static void main (String... arguments) throws IOException { File testFile = new File("C:\\Temp\\blah.txt"); System.out.println("Original file contents: " + getContents(testFile)); setContents(testFile, "The content of this file has been overwritten..."); System.out.println("New file contents: " + getContents(testFile)); } }