2011-01-02 2 views
0

Ниже приведен код игрушек, который демонстрирует мой вопрос. Первая - это версия, которая компилируется, а вторая - это версия, которая не компилируется.Java: Создание экземпляра локальных внутренних классов

В примере примера 1, чтобы создать экземпляр InnerClass, я должен создать экземпляр под определением класса InnerClass. Это имеет смысл, потому что над определением класса InnerClass не отображается. Однако, скажем, ради аккуратности, я хочу создать и использовать экземпляр InnerClass в верхней части foo(). Есть ли способ определить InnerClass на лету перед фактическим определением класса, чтобы мой код мог больше походить на пример 2, но будет ли законным Java?

пример 1

public class OuterClass { 
    public void foo() { 
     class InnerClass { 

      public InnerClass() { 
       // do nothing. 
      } 

     } 

     InnerClass in = new InnerClass(); // Defined below, and compiles! 

    } 
} 

пример 2

public class OuterClass { 
    public void foo() { 

     InnerClass in = new InnerClass(); // Defined above, does not compile! 

     class InnerClass { 

      public InnerClass() { 
       // do nothing. 
      } 

     } 

    } 
} 
+0

Какой компилятор вы используете? – Oded

+0

java version "1.5.0_26" Java (TM) 2 Runtime Environment, Standard Edition – Charlotte

+0

В чем проблема с определением класса перед его использованием? Я не вижу, какое преимущество у вас есть со вторым примером, даже если он сработает. –

ответ

3

Концептуально, локальный класс декларации заявление. Класс не существует до тех пор, пока оператор не будет выполнен. Класс также исчезает, когда область действия объявляется в конце. В общем случае локальный класс может ссылаться на другие локальные имена областей, поэтому порядок выполнения заказов важен.

void f() 
{ 
    if(true) 
     throw new Error(); 

    class InnerClass 
    { 
    ... 
    } 
} 

В этом примере InnerClass декларация заявление никогда не будет достигнуто, так что класс никогда не будет существовать. Предварительная ссылка на него была бы бессмысленной.

Это всегда хорошая идея, чтобы объявить что-то перед его использованием. В Java классы могут иметь круговые зависимости, поэтому Java должен позволить ссылаться на классы из синего - но не делайте этого, если этого можно избежать.

2

Вы можете определить внутренний класс вне метода, как

public class OuterClass { 
    public void foo() { 

     InnerClass in = new InnerClass(); // Defined above, does not compile! 


    } 

    class InnerClass { 
     public InnerClass() { 
      // do nothing. 
     } 
    } 
} 
+0

Это не отвечает на мой вопрос. Я хочу, чтобы класс был локальным внутренним классом. Если вы переместите его вне метода, то он больше не является локальным. – Charlotte

+3

@Charlotte: Просто нет способа создать локальный внутренний экземпляр класса до объявления класса. Вашими вариантами являются либо ваш первый пример, либо ответ Роба (который я определенно предпочитаю, так как в конце код будет более аккуратным). –

1

Звучит как много работы только ради аккуратности. Вот трюк с использованием анонимного внутреннего класса, который позволяет вам объявить экземпляр класса, у которого есть функциональные возможности, которые вы еще не определили, что похоже на то, что вы хотите.

Обратите внимание, что ограничение заключается в том, что вы должны определить интерфейс где-то раньше или повторно использовать существующий интерфейс, например Runnable. Вот пример:

public class OuterClass { 
    public void foo() { 
     // Declaration 
     Runnable anonymous; 

     // Implementation 
     anonymous = new Runnable() { 
      public void run() { 
       // do nothing. 
      } 
     }; 

     // Execution 
     anonymous.run(); 
    } 
} 
Смежные вопросы