2012-02-20 67 views
17

有没有任何情况下Class.getDeclaringClass可以给出与Class.getEnclosingClass不同的结果?封闭类vs申报类

我想这可能是与外部类实例化,这不是声明为静态内部类的子类的事,但我没能得到一个差方式:

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 
+0

你是什么目的? – MartinL 2012-02-20 11:11:54

+0

@MartinL:我有一个类'X',它声明了一个'MemberInnerClass',在我的例子中,我也有大量的'X'的子类, X'参与了'MemberInnerClass'的给定实例;我工作现在编辑一下,但对宣布封闭课程感到好奇。 – OpenSauce 2012-02-20 12:16:02

回答

24

这里http://kickjava.com/1139.htm#ixzz1mv2nEWg7实测值:

“与getDeclaringClass的诡计是匿名内部类不计为在第一个类的成员e 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 
    } 
}