2011-09-01 60 views
0

我在这里遇到了一个奇怪的结果,并不确定它是Java中的错误还是预期的行为。我有一个内部类,我已经使用反射来获取声明的字段(class.getDeclaredFields())。但是,当我遍历字段列表并检查单个类型时,“this”字段将返回外部类而不是内部类。JDK6中的内部类中的“this”错误的字段类型?

这是预期的行为?我觉得很奇怪。

例:

import java.lang.reflect.Field; 

public class OuterClass { 

    public class InnerClass{ 
     public String innerClassString; 
      public InnerClass innerClass; 

    } 


    public static void main(String[] args) { 

     // print the fields of the inner class 
     for(Field field : OuterClass.InnerClass.class.getDeclaredFields()) 
      System.out.println(field.getName() + " ::: " + field.getType()); 
    } 
} 

输出:

innerClassString ::: class java.lang.String 
innerClass ::: class OuterClass$InnerClass 
this$0 ::: class OuterClass 

我预计在$ 0是类型OuterClass.InnerClass的。

这是一个Java错误?无论如何要解决这种意外的行为?

谢谢,

埃里克

+4

99.99%,你几乎可以认为它不与被数以百万计的世界各地的开发框架的错误。 – StriplingWarrior

+0

我同意。不过,我之前在SO上看到过类似的帖子,指出Java7中修正了这个指针的一个错误,所以这让我感到惊讶。 (http://stackoverflow.com/questions/4823278/inner-class-type-parameter-bound-by-enclosing-class-type-variable) –

+0

'这个$ 0'是对外部类对象的引用。它本身不需要对Inner类对象的引用。即'this' –

回答

9

每个非静态内部类维护保持到它被实例化用于外类的引用的不可见的ivar。这就是this$0

将InnerClass更改为public static class并查看区别。

为了清楚起见,Oracle建议此术语:

http://download.oracle.com/javase/tutorial/java/javaOO/nested.html

术语:嵌套类分为两类:静态和非静态的。 声明为静态的嵌套类简单地称为静态嵌套类非静态嵌套类被称为内部类

...

的将InnerClass一个实例只能内的在OuterClass的实例存在并有方法及其外围实例字段的直接访问。 ...

要实例化一个内部类,您必须首先实例化外部类。然后,创建外部对象内的内部对象与此语法:

OuterClass.InnerClass innerObject = outerObject.new InnerClass(); 

===

有没有到这个$ 0变量的任何访问,然后从内部类中,如果你想?

在内部类的方法,你可以说:

OuterClass outer = OuterClass.this; 

System.out.println(OuterClass.this.toString()); 

这个这个特殊的变种 - OuterClass.this - 正在访问this$0伊娃 - 它将返回OuterClass实例。请注意,这与在InnerClass方法内使用常规this不同,后者将返回当前的InnerClass实例。

===

此外,我怎么能确定,如果我处理“这个$ 0”现场不使用字符串比较?

我不清楚你想做什么,所以我不能推荐如何实现你想要的。

+0

如果你想要的话,是否可以从内部类中访问这个$ 0变量?或者它是隐藏的,只能通过反射变量获得?此外,如何确定我是否在不使用字符串比较的情况下处理“$ 0”字段?希望在我的代码中继续执行if(field.getType()== classBeingProcessed.getClass()),但这显然不再可行。我唯一的选择是比较字符串吗? –

+0

本教程出错了。你可以在静态上下文中有一个内部类(比如静态方法),那么它没有包含实例。类的分类很混乱。 – irreputable