2010-05-20 2 views
4

Я создал нестатический внутренний класс как это:Должен ли внутренний класс быть статическим в Java?

class Sample { 
    public void sam() { 
     System.out.println("hi"); 
    }  
} 

я назвал его main способа, как это:

Sample obj = new Sample(); 
obj.sam(); 

Это дало ошибку компиляции: non-static cannot be referenced from a static context Когда я объявил нестатические внутренний класс как статический, он работает. Почему это так?

+1

Возможно, вы могли бы показать нам больше кода, например, окружающего класса. Пожалуйста, укажите пример, который люди могут просто скопировать + вставить, чтобы попробовать сами. –

+1

есть ** огромная ** разница между «ошибкой компиляции» и «исключением». Пожалуйста, обратите внимание на это :) Я также включил фактическое сообщение об ошибке вместо неопределенной фразы «нестатический класс класса или что-то в этом роде». Также обратите внимание на это в будущих вопросах :) – BalusC

ответ

9

Для нестатического внутреннего класса, компилятор автоматически добавляет скрытую ссылку на экземпляр объекта «владелец». Когда вы пытаетесь создать его из статического метода (скажем, метода main), нет экземпляра-владельца. Это похоже на попытку вызвать метод экземпляра из статического метода - компилятор не позволит этого, потому что на самом деле у вас нет экземпляра для вызова.

Таким образом, внутренний класс должен быть либо статическим (в этом случае не требуется экземпляр владельца), либо создается только экземпляр внутреннего класса из нестатического контекста.

4

нестатические внутренний класс имеет внешний класс в качестве переменного экземпляра, что означает, что он может быть реализован только из такого экземпляра внешнего класса:

public class Outer{ 
    public class Inner{ 
    } 

    public void doValidStuff(){ 
     Inner inner = new Inner(); 
     // no problem, I created it from the context of *this* 
    } 

    public static void doInvalidStuff(){ 
     Inner inner = new Inner(); 
     // this will fail, as there is no *this* in a static context 
    } 

} 
+1

Это НЕправда. См. Мой собственный ответ здесь –

+0

все, что я написал, правда, но слово «только». и в идеальном мире это тоже должно быть правдой, потому что инстанцирование, упомянутое в вашем ответе, - ужасный стиль. –

+0

@Eugene, ваш ответ не опровергает это ... у вас есть новый A() в вашем ответе, который в точности соответствует тому, что означает среднее значение «можно только создать из такого экземпляра». И я должен согласиться, это ужасный стиль ... – Vinze

2

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

public class A { 

    public static void main(String[] args) { 
    new A(). new B().a(); 
    } 

    class B { 
    public void a() { 
     System.err.println("AAA"); 
    } 
    } 

} 
+1

arghhh, это ужасный стиль и приводит к почти незаметному коду !!! –

+0

Никто не предлагает, следует ли это использовать или нет. Это не то, что задавал первоначальный вопрос. –

+0

, когда начинающий задает такой вопрос, просьба о предоставлении рекомендаций по передовым методам подразумевает ИМО. Есть много особенностей языка, которые, как правило, путают начинающих (например, динамические блоки инициализатора и т. Д.), И я думаю, что их не следует упоминать новичкам, пока он специально не попросит их –

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