java - 封闭类与声明类

标签 java reflection

在任何情况下 Class.getDeclaringClass 可能会给出与 Class.getEnclosureClass 不同的结果?

我认为这可能与外部类的子类实例化一个未声明为静态的内部类有关,但我无法通过这种方式获得差异:

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

最佳答案

在这里找到 http://kickjava.com/1139.htm#ixzz1mv2nEWg7 :

“getDeclaringClass 的微妙之处在于,匿名内部类在 Java 语言规范中不计为类的成员,而命名内部类则计入。因此,此方法为匿名类返回 null。替代方法 getEnclosureClass 适用于匿名类和命名的类。”

例如:

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
  }
}

关于java - 封闭类与声明类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9360072/

相关文章:

java - 用自定义类替换 Java API 类?

java - Oracle:OALL8 处于不一致状态

c# - 如何在编译后更改 AssemblyName 以在 Unity3d 中作为 mod 加载

php - 使用反射通过引用传递参数

java - 如何使用 java 归档文件修订安全?

java - 在 java.lang.reflect.Proxy 对象上调用扩展函数时的 Kotlin 奇怪行为

Ruby - define_method 和闭包

java - 为 maven-processor-plugin 编写注解处理器

java - 如何避免使用 Spring-Boot 下载嵌入式 MongoDb

java - 使用 java 进行英语到西类牙语翻译