Advanced   Java   Services local classes Back Next Up Home


Orte der Deklaration

Eine lokale Klasse kann da deklariert werden, wo auch lokale Variablen definiert werden, also etwa innerhalb einer Methode oder auch innerhalb eines Blocks. Das folgende Beispiel zeigt die grundsätzlichen Orte an, an denen lokale Klassen eingeführt werden können.

public class LocalClassDemo
{
   // anonymous initializer (anonymer Konstruktor)
   {
      class LocalClass  // local class in non-static context
      {
      }
   }

   static  // static initializer (statischer Konstruktor)
   {
      class LocalClass  // local class in static context
      {
      }
   }

   public void nonStaticMethod(int a)
   {
      class LocalClass  // local class in non-static context
      {
      }

      if (a>0)
      {
         class AnotherLocalClassInNonStaticContext
         {
         }
      }
   }

   public static void staticMethod(int a)
   {
      class LocalClass  // local class in static context
      {
      }

      if (a>0)
      {
         class AnotherLocalClassInStaticContext
         {
         }
      }
   }

   // inneres interface
   private interface Face
   {
      class NotALocalClass  // top-level-class !!
      {
      }
   }

   public static void main(String[] args)
   {
      LocalClassDemo.Face.NotALocalClass x = new LocalClassDemo.Face.NotALocalClass() ;
   }
}

Im obigen Beispiel werden sechs lokale Klassen deklariert, von denen vier denselben Namen haben. Da der Gültigkeitsbereich auf einen Block beschränkt ist, gibt es keine Namensprobleme. Anders als bei Memberklassen muß eine lokale Klasse vor ihrer Verwendung deklariert werden, damit der Compiler sie kennt.

public void aMethod()
{
   //LocalClass lc1 = new LocalClass();   Fehlermeldung des Compilers: cannot resolve symbol

   class LocalClass  // local class in non-static context
   {
   }

   LocalClass lc2 = new LocalClass();  // OK !
}

Wie bei lokalen Variablen gibt es auch für die lokale Klasse keinen Schutzzustand, die Deklaration von etwa public class Xxx führt zu der Fehlermeldung illegal start of expression.


Zugriff auf äußere Variablen

Für eine lokale Klasse gibt es zweierlei Arten von äußeren Variablen, zum einen die Memberdaten der umschließenden Klasse und zum anderen die lokalen Variablen im Kontext des Blockes, wo die lokale Klasse angesiedelt ist.


Zugriff auf Membervariablen

Steht die lokale Klasse in einem nichtstatischen Kontext, so hat sie Zugriff auf alle Membervariablen, wie das folgende Beispiel zeigt

public class LocalClassDemo
{
   private int nichtStatisch;
   private static int schonStatisch;

   // anonymous initializer (anonymer Konstruktor)
   {
      class LocalClass  // local class in non-static context
      {
         private int a = nichtStatisch;
         private int b = schonStatisch;
      }
   }
}

Steht die lokale Klasse dagegen in einem statischen Kontext, so hat sie nur Zugriff auf statische Members, wie das folgende Beispiel zeigt.

public class LocalClassDemo
{
   private int nichtStatisch;
   private static int schonStatisch;

   static  // static initializer (statischer Konstruktor)
   {
      class LocalClass  // local class in static context
      {
         //private int a = nichtStatisch;  NOK
         // non-static variable nichtStatisch cannot be referenced from a static context

         private int b = schonStatisch; // OK
      }
   }
}

Für die lokale Klasse spielt der Schutzzustand etwa der Variablen nichtStatisch keine Rolle. Wie üblich bezieht sich dieser nur nach außen.


Zugriff auf lokale Variablen

Objekte von Klassen werden grundsätzlich auf dem Heap angelegt, das hat zur Folge, daß ein Objekt einer lokalen Klasse auch dann noch existiert, wenn die Methode schon beendet ist. Das gleiche ist etwa auch der Fall bei Arrays, die lokal in einer Methode angelegt werden. Aus diesem Grund kann man sie ja auch gefahrlos über return zurückgeben und dann immer noch auf sie zugreifen. Man erhält eine Kopie des Zeigers auf das Objekt und greift damit auf das Objekt zu. Der lokale Zeiger dagegen "stirbt" mit dem Ende der Methode. Aus diesem Grund darf eine lokale Klasse nur auf solche lokalen Variablen zugreifen, die konstant sind.

class LocalClassDemo
{
   public static void aMethod(final int a)
   {
      int b ;

      class LocalClass
      {
         //private int b = a ;  NOK
         // local variable a is accessed from within inner class; needs to be declared final

         private int d = a ;  // OK !
      }
   }
}

Ein Beispiel

Die folgende Methode ermittelt zu einem übergebenen Verzeichnis vom Typ File eine Liste der in diesem Verzeichnis liegenden html-Files und Directories. Dazu wird eine lokale Klasse geschrieben, die das Interface FileFilter implementiert. Die zu schreibende Methode accept ist so ausgelegt, daß nur Verzeichnisse und html-Files akzeptiert werden. Ein von dieser Klasse angelegtes FilterObjekt wird dann der Methode listFiles() der Klasse File übergeben (natürlich braucht man am Anfang des Beispiels mal ein import java.io.*;). Das ganze könnte man auch als anonyme Klasse schreiben und damit zum new- Aufruf dazupacken, aber die Trennung von Klasse und Objekt macht den Code übersichtlicher.

private File[] getDirAndHTMLFileList(File dir)
{
   // local class
   class HTMLFilter implements FileFilter
   {
      public boolean accept(File pathname)
      {
         if ( pathname.isDirectory() )
            return true;

         String name = pathname.getName().toLowerCase() ;

         if (name.endsWith(".htm") || name.endsWith(".html") )
            return true;

         return false;
      }
   }

   return dir.listFiles( new HTMLFilter() )  ;
}


Namen der BytecodeDateien

Der Compiler speichert jede Klasse als eigene Datei. Für das einleitende Beispiel erzeugt der Compiler die folgenden Dateien:

Valid XHTML 1.0 Strict top Back Next Up Home