 <p>Without using a local variable, in most invocations we have effectively</p> <pre><code>if(field!=null) // true return field; </code></pre> <p>so there are two volatile reads, which is slower than one volatile read.</p> <p>Actually JVM can merge the two volatile reads into one volatile read and still conform to JMM. But we expect JVM to perform a good faith volatile read every time it's told to, not to be a smartass and try to optimize away any volatile read. Consider this code</p> <pre><code>volatile boolean ready; do{}while(!ready); // busy wait </code></pre> <p>we expect JVM to really load the variable repeatedly.</p>