2014-01-25 4 views
3

Если я не могу создать экземпляр статического класса, почему я могу создать экземпляр статического внутреннего класса?Почему я могу создать статический внутренний класс?

В коде сильфоне, счетчик статический внутренний класс, но он может быть реализован, как если бы это не было:

public class Task { 

    static class Counter { 
     int counter = 0; 
     void increment() {counter++;} 
    } 

    public static void main(String[] args) { 
     Counter counter1 = new Task.Counter(); 
     Counter counter2 = new Task.Counter(); 
     counter1.increment(); 
     counter2.increment(); 
     counter2.increment(); 
     counter2.increment(); 
     System.out.println("counter1: " + counter1.counter); 
     System.out.println("counter2: " + counter2.counter); 
    } 
} 

Если счетчик не статический класса, он cound быть экземпляром, используя следующий синтаксис:

Counter counter1 = new Task().new Counter(); 
Counter counter2 = new Task().new Counter(); 

Но я не могу понять разницу между этими подходами в практических целях.

+0

Возможный дубликат [внутренний класс Java и статический вложенный класс] (http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class) – Mark

+0

Спасибо, но я не согласен , потому что упомянутый вопрос объясняет разницу между внутренними и вложенными классами. Я спрашиваю, почему я могу создать статический внутренний класс, как если бы он не был статичным. По моему скромному мнению, это не одно и то же. Но я уважаю вашу точку зрения. – outlookrperson

+0

Это то же самое, что и вызывать 'thread.yield()' или 'Thread.yield()' –

ответ

4

В коде сильфона, счетчик статический внутренний класс, но он может быть реализован, как если бы это не было:

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

Counter counter1 = new Task.Counter(); 

Здесь вы создаете экземпляр Counter. Но так как Counter - это вложенный класс (это то, что мы называем классом static inner), мы должны получить к нему доступ именно так. Task.Counter - это полное имя класса Counter (добавьте туда пакет). В самом деле, так как ваш метод main в только Task класса, вы можете напрямую использовать:

Counter counter1 = new Counter(); 

Теперь, inner class (не статический), вы не можете получить доступ к этому классу без любого экземпляра ограждающих класс. Таким образом, чтобы создать экземпляр Counter, сначала нужно экземпляр Task, как это:

Task task = new Task(); 
Counter counter = task.new Counter(); 

Вы можете комбинировать эти заявления в одну, как это:

Counter counter = new Task().new Counter(); 

Простыми словами, разница что inner class имеет ссылку на прилагаемый экземпляр, связанный с ним, который nested class не имеет такой ссылки.

+0

Спасибо, хорошее объяснение. Но внутренние классы и вложенные классы не являются синонимами? – outlookrperson

+0

@rperson Нет. Классы 'static inner' часто называют просто« вложенным классом ». И «нестатические внутренние» классы просто называются «внутренним классом». –

+0

Я вижу.Это всего лишь вопрос терминологии. Благодарю. – outlookrperson

0

Статический вложенный класс не имеет доступа к нестатическим полям и методам класса, в котором он вложен. В экземпляре класса вложенности существует нестатический вложенный класс («внутренний класс»), поэтому он имеет доступ к своим нестатическим полям и методам.

Смежные вопросы