[英]Getting hold of the outer class object from the inner class object
I have the following code.我有以下代码。 I want to get hold of the outer class object using which I created the inner class object
inner
.我想获取外部类对象,我使用它创建了内部类对象
inner
。 How can I do it?我该怎么做?
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 :-( ");
}
}
}
EDIT: Well, some of you guys suggested of modifying the inner class by adding a method:编辑:嗯,你们中的一些人建议通过添加一个方法来修改内部类:
public OuterClass outer() {
return OuterClass.this;
}
But what if I don't have control to modify the inner class, then (just to confirm) do we have some other way of getting the corresponding outer class object from the inner class object?但是如果我没有控制修改内部类,那么(只是为了确认)我们是否有其他方法可以从内部类对象中获取相应的外部类对象?
Within the inner class itself, you can use OuterClass.this
.在内部类本身中,您可以使用
OuterClass.this
。 This expression, which allows to refer to any lexically enclosing instance, is described in the JLS as Qualified this
.这个表达式允许引用任何词法封闭实例,在 JLS 中被描述为Qualified
this
。
I don't think there's a way to get the instance from outside the code of the inner class though.我认为没有办法从内部类的代码之外获取实例。 Of course, you can always introduce your own property:
当然,你可以随时介绍自己的财产:
public OuterClass getOuter() {
return OuterClass.this;
}
EDIT: By experimentation, it looks like the field holding the reference to the outer class has package level access - at least with the JDK I'm using.编辑:通过实验,看起来保存对外部类的引用的字段具有包级别访问权限 - 至少对于我正在使用的 JDK。
EDIT: The name used ( this$0
) is actually valid in Java, although the JLS discourages its use:编辑:使用的名称(
this$0
)是Java实际上是有效的,虽然JLS阻碍了它的用法:
The
$
character should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems.$
字符应该只在机械生成的源代码中使用,或者很少用于访问遗留系统上预先存在的名称。
OuterClass.this
引用外部类。
You could (but you shouldn't) use reflection for the job:你可以(但你不应该)在工作中使用反射:
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);
}
}
Of course, the name of the implicit reference is utterly unreliable, so as I said, you shouldn't :-)当然,隐式引用的名称完全不可靠,所以正如我所说,你不应该:-)
The more general answer to this question involves shadowed variables and how they are accessed.对这个问题的更一般的回答涉及影子变量及其访问方式。
In the following example (from Oracle), the variable x in main() is shadowing Test.x :在以下示例中(来自 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();
}
}
Running this program will print:运行这个程序将打印:
x=0, Test.this.x=1
More at: http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6更多信息: http : //docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
Here's the example:这是示例:
// 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";
}
}
if you don't have control to modify the inner class, the refection may help you (but not recommend).如果您无法控制修改内部类,反射可能会对您有所帮助(但不推荐)。 this$0 is reference in Inner class which tells which instance of Outer class was used to create current instance of Inner class.
this$0 是内部类中的引用,它告诉我们使用外部类的哪个实例来创建内部类的当前实例。
I have the following code.我有以下代码。 I want to get hold of the outer class object using which I created the inner class object
inner
.我想掌握使用外部类对象创建内部类对象
inner
。 How can I do it?我该怎么做?
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 :-( ");
}
}
}
EDIT: Well, some of you guys suggested of modifying the inner class by adding a method:编辑:嗯,你们中的一些人建议通过添加方法来修改内部类:
public OuterClass outer() {
return OuterClass.this;
}
But what if I don't have control to modify the inner class, then (just to confirm) do we have some other way of getting the corresponding outer class object from the inner class object?但是,如果我没有控制权来修改内部类,那(只是确认一下),我们还有其他方法可以从内部类对象中获取相应的外部类对象吗?
/**
* Not applicable to Static Inner Class (nested class)
*/
public static Object getDeclaringTopLevelClassObject(Object object) {
if (object == null) {
return null;
}
Class cls = object.getClass();
if (cls == null) {
return object;
}
Class outerCls = cls.getEnclosingClass();
if (outerCls == null) {
// this is top-level class
return object;
}
// get outer class object
Object outerObj = null;
try {
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
if (field != null && field.getType() == outerCls
&& field.getName() != null && field.getName().startsWith("this$")) {
field.setAccessible(true);
outerObj = field.get(object);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return getDeclaringTopLevelClassObject(outerObj);
}
Of course, the name of the implicit reference is unreliable, so you shouldn't use reflection for the job.当然,隐式引用的名称是不可靠的,因此您不应该对作业使用反射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.