2013-08-13 2 views
1

enter image description hereПочему статический вложенный класс не может получить доступ к этому «указателю» внешнего класса?

Вещь, которая беспокоит меня, является второй точкой.

Я думал, что это может быть связано с тем, что «этот» указатель не является статичным, и поэтому внутренний класс не может получить к нему доступ. Я не уверен, что это правильное объяснение.

Это также подняло для меня еще один вопрос, который был «где« этот »указатель определен?»

+0

Imagine с помощью 'TopClass.this' в' static' метода. –

ответ

11

Разница между static вложенным классом и тот, который не static именно, что экземпляр не-static внутреннего класса связан с конкретным экземпляром класса ограждающего, в то время как static внутреннего класс не является. Там is нет A.this для экземпляра внутреннего класса static, с которым необходимо связать.

+0

Спасибо, это дало понять :) – Shookie

+0

Еще одна вещь, когда вы говорите, что внутренний класс связан с конкретным экземпляром охватывающего класса, означает ли это, что я могу изменить экземпляр, с которым он связан? – Shookie

+0

Нет, вы не можете; его ссылка «ParentClass.this» назначается, когда она создана, и все. – chrylis

2

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

public class A { 
    public static class B { 
    } 

    public class C { 
    } 
} 

затем экземпляр B и C вы должны сделать это следующим образом:

// simply 
A.B b = new A.B(); 
// however 
A.C c = new A().new C(); 

За кулисами, когда не- static внутренний класс экземпляр экземпляра охватывающего класса передается в конструктор. Таким образом, из-за этого доступен экземпляр OuterClass.this.

Для проверки «за кадром», что вы можете проверить заявленные конструкторами и объявленную полей внутреннего класса с помощью отражения:

// prints that there is one field of type A called "this$1" 
for (Field f : A.C.class.getDeclaredFields()) { 
    System.out.println(f); 
} 

// prints that the constructor takes in one parameter of type A 
for (Constructor c : A.C.class.getDeclaredConstructors()) { 
    System.out.println(c); 
}