<p>Mixing the use of primitive data types and their respective wrapper classes, in Java, can lead to a lot of bugs. The following example illustrates the issue:</p>

<pre><code>int i = 4;
...
if (i == 10)
  doStuff();
</code></pre>

<p>Later on you figure that you want the variable <em>i</em> to be either defined or undefined, so you change the above instantiation to:</p>

<pre><code>Integer i = null;
</code></pre>

<p>Now the equality check fails.</p>

<p>Is it good Java practise to always use the primitive wrapper classes? It obviously would get some bugs out of the way early, but what are the downsides to this? Does it impact performance or the application's memory footprint? Are there any sneaky gotchas?</p>

Firstly, switching from using a primitive to using an object just to get the ability to set it to null is probably a bad design decision.  I often have arguments with my coworkers about whether or not null is a sentinel value, and my opinion is usually that it is not (and thus shouldn't be prohibited like sentinel values should be), but in this particular case you're going out of your way to use it as a sentinel value.  Please don't.  Create a boolean that indicates whether or not your integer is valid, or create a new type that wraps the boolean and integer together.
Usually, when using newer versions of Java, I find I don't need to explicitly create or cast to the object versions of primitives because of the auto-boxing support that was added some time in 1.5 (maybe 1.5 itself).