2012-02-20 65 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 
    } 
}