2012-02-20 10 views
17

¿Hay alguna circunstancia en la que Class.getDeclaringClass podría dar un resultado diferente de Class.getEnclosingClass?Clase de inclusión vs Clase declarante

pensé que puede ser que ver con una subclase de la clase externa crear instancias de una clase interna que no fue declarado como estático, pero no fue capaz de obtener una diferencia de esa manera:

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()); 
    } 
} 

salida :

class Main 
class Main 
class Main 
class Main 
class Main 
class Main 
+0

¿cuál es su propósito ? – MartinL

+0

@MartinL: Tengo una clase 'X' que declara' MemberInnerClass', en la terminología de mi ejemplo. También tengo una gran cantidad de subclases de 'X'. Tenía una posible necesidad de determinar qué subclase de' X' estuvo involucrado en una instancia determinada de 'MemberInnerClass'; he trabajado ed alrededor de esto ahora, pero tenía curiosidad por declarar vs clase adjunta. – OpenSauce

Respuesta

24

encontrado aquí http://kickjava.com/1139.htm#ixzz1mv2nEWg7:

"La sutileza con getDeclaringClass es que las clases internas anónimas no se cuentan como miembro de una clase en º e Especificación del lenguaje Java, mientras que las clases internas con nombre son. Por lo tanto, este método devuelve null para una clase anónima. El método alternativo getEnclosingClass funciona para ambas clases anónimas y con nombre "

Por ejemplo:.

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(); 
    } 
} 

Lo mismo vale para las clases no anónimas en un ámbito de método:

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