封闭类 vs 声明类

23

Class.getDeclaringClassClass.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

@MartinL:我有一个声明了MemberInnerClass的类X,以我的例子术语来说。我还有很多X的子类。我曾经需要确定给定MemberInnerClass实例所涉及的X子类,现在我已经解决了这个问题,但是对于声明与封闭类之间的区别感到好奇。 - OpenSauce
1个回答

34

以下内容摘自此处:

「使用 getDeclaringClass 的难点在于,Java 语言规范将匿名内部类视为不属于类的成员,而将具名内部类视为属于类的成员。因此,对于匿名类,该方法返回 null。另一种方法 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
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接