我有下面的代码。我想获得外部类对象,我使用它创建了内部类对象inner。我该怎么做呢?

public class OuterClass {

    public class InnerClass {
        private String name = "Peakit";
    }

    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        InnerClass inner = outer.new InnerClass();
       // How to get the same outer object which created the inner object back?
        OuterClass anotherOuter = ?? ;

        if(anotherOuter == outer) {
             System.out.println("Was able to reach out to the outer object via inner !!");
        } else {
             System.out.println("No luck :-( ");
        }
    }
}

编辑:嗯,有些人建议通过添加一个方法来修改内部类:

public OuterClass outer() {
   return OuterClass.this;
}

但是如果我没有修改内部类的控制,那么(只是确认一下)我们是否有其他方法从内部类对象中获得相应的外部类对象?


当前回答

这个问题的更一般的答案涉及阴影变量以及如何访问它们。

在下面的例子中(来自Oracle), main()中的变量x遮蔽了Test.x:

class Test {
    static int x = 1;
    public static void main(String[] args) {
        InnerClass innerClassInstance = new InnerClass()
        {
            public void printX()
            {
                System.out.print("x=" + x);
                System.out.println(", Test.this.x=" + Test.this.x);
            }
        }
        innerClassInstance.printX();
    }

    public abstract static class InnerClass
    {
        int x = 0;

        public InnerClass() { }

        public abstract void printX();
    }
}

运行这个程序将输出:

x=0, Test.this.x=1

更多信息请访问:http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

其他回答

这个问题的更一般的答案涉及阴影变量以及如何访问它们。

在下面的例子中(来自Oracle), main()中的变量x遮蔽了Test.x:

class Test {
    static int x = 1;
    public static void main(String[] args) {
        InnerClass innerClassInstance = new InnerClass()
        {
            public void printX()
            {
                System.out.print("x=" + x);
                System.out.println(", Test.this.x=" + Test.this.x);
            }
        }
        innerClassInstance.printX();
    }

    public abstract static class InnerClass
    {
        int x = 0;

        public InnerClass() { }

        public abstract void printX();
    }
}

运行这个程序将输出:

x=0, Test.this.x=1

更多信息请访问:http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

下面是例子:

// Test
public void foo() {
    C c = new C();
    A s;
    s = ((A.B)c).get();
    System.out.println(s.getR());
}

// classes
class C {}

class A {
   public class B extends C{
     A get() {return A.this;}
   }
   public String getR() {
     return "This is string";
   }
}

你可以(但不应该)使用反射来完成这项工作:

import java.lang.reflect.Field;

public class Outer {
    public class Inner {
    }

    public static void main(String[] args) throws Exception {

        // Create the inner instance
        Inner inner = new Outer().new Inner();

        // Get the implicit reference from the inner to the outer instance
        // ... make it accessible, as it has default visibility
        Field field = Inner.class.getDeclaredField("this$0");
        field.setAccessible(true);

        // Dereference and cast it
        Outer outer = (Outer) field.get(inner);
        System.out.println(outer);
    }
}

当然,暗指的名字是完全不可靠的,所以如我所说,你不应该:-)

如果您无法控制修改内部类,反射可能会帮助您(但不推荐)。这个$0是内部类中的引用,它告诉外部类的哪个实例被用于创建内部类的当前实例。

OuterClass。这引用了外部类。