Класс вложения против объявления класса - PullRequest
23 голосов
/ 20 февраля 2012

Есть ли обстоятельства, при которых 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 Ответ

32 голосов
/ 20 февраля 2012

Найдено здесь http://kickjava.com/1139.htm#ixzz1mv2nEWg7:

"Подтип с 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
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...