Класс вложения против объявления класса
Есть ли обстоятельства, при которых Class.getDeclaringClass
может дать другой результат от Class.getEnclosingClass
?
Я думал, что это может быть связано с подклассом внешнего класса, создающим экземпляр внутреннего класса, который не был объявлен как статический, но я не смог получить разницу таким образом:
public class Main {
private static class StaticInnerClass {
}
private class MemberInnerClass {
}
private static class ChildClass extends Main {
}
public MemberInnerClass getMemberInnerClassInstance() {
return new MemberInnerClass();
}
public static void main(String[] args) {
System.out.println( StaticInnerClass.class.getDeclaringClass() );
System.out.println( StaticInnerClass.class.getEnclosingClass() );
System.out.println( MemberInnerClass.class.getDeclaringClass() );
System.out.println( MemberInnerClass.class.getEnclosingClass() );
System.out.println( new ChildClass().getMemberInnerClassInstance().getClass().getEnclosingClass() );
System.out.println( new ChildClass().getMemberInnerClassInstance().getClass().getDeclaringClass() );
}
}
Выход:
class Main
class Main
class Main
class Main
class Main
class Main
1 ответ
Нашел здесь http://kickjava.com/1139.htm:
"Недостатком метода getDeclaringClass является то, что анонимные внутренние классы не учитываются как члены класса в спецификации языка Java, тогда как именованные внутренние классы таковы. Поэтому этот метод возвращает ноль для анонимного класса. Альтернативный метод getEnclosingClass работает как для анонимных, так и для именованных классов.".
Например:
public class Test {
public static void main(String[] args) {
new Object() {
public void test() {
System.out.println(this.getClass().getDeclaringClass()); //null
System.out.println(this.getClass().getEnclosingClass()); //not null
}
}.test();
}
}
То же самое относится и к неанонимным классам в области видимости метода:
class Foo {
Class<?> bar() throws NoSuchFieldException {
class Bar<S> { }
return Bar.class;
}
static void main(String[] args) throws NoSuchFieldException {
System.out.println(new Foo<Void>().bar().getDeclaringClass()); // null
System.out.println(new Foo<Void>().bar().getEnclosinglass()); // Foo
}
}