2.4 Blöcke, Initialisierung und Sichtbarkeit 

2.4.1 Blöcke und Anweisungen 

Ein Block fasst eine Gruppe von Anweisungen zusammen, die hintereinander ausgeführt werden. Anders gesagt: Ein Block ist eine Anweisung, die in den geschweiften Klammern { } eine Folge von Anweisungen zu einer neuen Anweisung zusammenfasst.
{ Anweisung1; Anweisung2; ... }
Ein Block kann überall dort verwendet werden, wo auch eine einzelne Anweisung stehen kann. Der neue Block hat jedoch eine Besonderheit für Variablen, da er einen lokalen Bereich für die darin befindlichen Anweisungen inklusive der Variablen bildet.
Leerer Block und geschachtelte Blöcke
Ein Block ohne Anweisung nennt sich leerer Block. Er verhält sich wie eine leere Anweisung, also wie ein Semikolon. Da Blöcke auch geschachtelt werden können, ist Folgendes in der Funktion main() in Ordnung:
public static void main( String[] args ) { { System.out.println( "Hallo Computer" ); {{}}{{}{}}} }
2.4.2 Initialisierung von lokalen Variablen 

Die Laufzeitumgebung – beziehungsweise der Compiler – initialisiert lokale Variablen nicht automatisch mit einem Nullwert. Vor dem Lesen müssen lokale Variablen von Hand initialisiert werden. [Anders ist das bei Objektvariablen (und statischen Variablen sowie Feldern). Sie sind standardmäßig mit null (Referenzen), 0 (bei Zahlen) oder false belegt.]
int age; boolean adult; System.out.println( age ); // Local variable age may not have been initialized. age = 18; if ( age >= 18 ) adult = true; System.out.println( adult ); // Local variable adult may not have been initialized.
Die beiden lokalen Variablen age und adult werden nicht automatisch initialisiert, und so kommt es bei der versuchten Ausgabe von age zu einem Compilerfehler, da ein Lesezugriff nötig ist, aber vorher noch kein Schreibzugriff stattfand. Erst die nächste Zeile mit age = 18 ist in Ordnung.
Weil Zuweisungen in bedingten Anweisungen vielleicht nicht ausgeführt werden, meldet der Compiler auch einen Fehler, wenn er sich vorstellen kann, dass es einen Programmfluss ohne die Zuweisung gibt. Da adult nur nach der if-Abfrage auf den Wert true gesetzt wird, wäre nur unter der Bedingung age größer gleich 18 ein Schreibzugriff auf adult erfolgt und ein folgender Lesezugriff möglich. Doch da der Compiler annimmt, dass es andere Fälle geben kann, wäre ein Zugriff auf eine nicht initialisierte Variable ein Fehler.
Eclipse gibt einen Hinweis und Verbesserungsvorschlag, wenn eine lokale Variable nicht initialisiert ist.
2.4.3 Sichtbarkeit und Gültigkeitsbereich 

In jedem Block und auch in jeder Klasse [Die so genannten Objektvariablen oder Klassenvariablen, doch dazu später mehr.] können Variablen deklariert werden. Jede Variable hat einen Geltungsbereich (engl. scope), auch Gültigkeitsbereich beziehungsweise Lebensdauer genannt. Sie ist nur in dem Block »lebendig«, in dem sie deklariert wurde. In dem Block ist die Variable lokal. Dazu ein Beispiel mit zwei Funktionen:
public static void main( String[] args ) { int foo; { int bar; // bar gilt nur in dem Block } bar = 2; // Fehler: bar cannot be resolved } static void qux() { int foo, baz; // foo hat nichts mit foo aus main() zu tun { int baz; // Fehler: Duplicate local variable baz! } }
Zu jeder Zeit können Blöcke aufgebaut werden. Außerhalb des Blocks sind deklarierte Variablen nicht sichtbar. Nach Abschluss des inneren Blocks, der bar deklariert, ist ein Zugriff auf bar nicht mehr möglich; auf foo ist der Zugriff innerhalb der Funktion main() weiterhin erlaubt. Dieses foo ist aber ein anders foo als in der Funktion qux().
Innerhalb eines Blocks können Variablennamen nicht genauso gewählt werden wie Namen lokaler Variablen eines äußeren Blocks oder wie die Namen für die Parameter einer Funktion. Das zeigt die zweite Funktion am Beispiel der Deklaration baz. Obwohl andere Programmiersprachen diese Möglichkeit erlauben – und auch eine Syntax anbieten, um auf eine überschriebene lokale Variable eines höheren Blocks zuzugreifen –, haben sich die Java-Sprachentwickler dagegen entschieden. Das ist auch gut so, denn dies minimiert Fehlerquellen.