Initialization
Typically, try to initialize variables when they are declared.
If the value of the variable is not changed, make it explicit using the final
keyword. This will help you justify the correctness of your code, and although I do not know the compiler optimizers or JVMs that recognize the final
keyword, they will certainly be possible.
Of course, there are exceptions to this rule. For example, a variable may be assigned in if if n else; else or switch. In this case, an โemptyโ declaration (without initialization) is preferable to initialization, which is guaranteed to be overwritten before the dummy value is read.
Color color = null; switch(colorCode) { case RED: color = new Color("crimson"); break; case GREEN: color = new Color("lime"); break; case BLUE: color = new Color("azure"); break; } color.fill(widget);
You now have a NullPointerException
if an unrecognized color code is presented. It is better not to assign meaningless null
. The compiler will color.fill()
error when calling color.fill()
because it will detect that you could not initialize color
.
To answer your question in this case, I will need to see this code. If the solution initialized it inside the run()
method, it should have been used either as a temporary storage or as a way to "return" the results of the task.
If the collection is used as temporary storage and is not accessible outside the method, it should be declared as a local variable, not an instance variable, and most likely should be initialized where it is declared in the method.
Concurrency Problems
To start the programming course, your teacher probably did not try to confront you with the complexities of parallel programming, although if so, I'm not sure why you used Thread
. But, given the current trends in CPU design, anyone learning to program should have a clear understanding of concurrency. I will try to go deeper here a little deeper.
The returned results from the thread run
method are a bit more complicated. This method is a Runnable interface, and nothing stops multiple threads from executing the run
method of a single instance. The resulting concurrency problems are part of the motivation for the Callable interface introduced in Java 5. This is very similar to Runnable
, but can return a thread-safe way and throw an Exception
if the task cannot be completed.
This is a bit of a digression, but if you're interested, consider the following example:
class Oops extends Thread { private int counter = 0; private Collection<Integer> state = ...; public void run() { state.add(counter); counter++; } public static void main(String... argv) throws Exception { Oops oops = new Oops(); oops.start(); Thread t2 = new Thread(oops); t2.start(); ... } }
At the end of the main
method, you hardly know what the โstateโ of Collection
. Two threads work on it at the same time, and we did not indicate whether the collection is safe for simultaneous use. If we initialize it inside the stream, at least we can say that ultimately state
will contain one element, but we cannot say whether it will be 0 or 1.