java中this$0的含义及用法,具体case是这样的:
通过测试工具去探测界面UI上的控件FlatButton实例对象,但是拿到的最终对象是FlatButton的内部类TextButton对象,
所以这里需要从一个内部类的实例拿到所在外部类的实例,this$0这时就派上用处了。
示例方案如下:
//通过工具获取到TextButton实例对象
textButton=getButtonByToolMethod ();
//获取内部类TextButton的一个字段this$0信息
//this$0特指该内部类所在的外部类的引用,不需要手动定义,编译时自动加上
Filed outerField=textButton.getClass().getDeclaredField("this$0");
//this$0是私有的,提升访问权限
outerField.setAccessible(true);
//拿到该字段上的实例值
FlatButton flatButton=(FlatButton)outerField.get(textButton);
this$0就是内部类所自动保留的一个指向所在外部类的引用。
另外,受到$后的数字0启发,发现原来数字还可以有1,2,3..., 具体可以看如下代码就一清二楚了.
//Outer.java
public class Outer {//this$0
public class FirstInner {//this$1
public class SecondInner {//this$2
public class ThirdInner {
}
}
}
public static void main(String[] args) throws Exception{
//初始化各内外实例
Outer test = new Outer();
FirstInner first = test.new FirstInner();
FirstInner.SecondInner second = first.new SecondInner();
FirstInner.SecondInner.ThirdInner third=second.new ThirdInner();
//Outer,this$0
Field outerfield = first.getClass().getDeclaredField("this$0");
outerfield.setAccessible(true);
Object object = outerfield.get(first);
System.out.println(object instanceof Outer);
//FirstInner,this$1
Field firstInnerfied = second.getClass().getDeclaredField("this$1");
firstInnerfied.setAccessible(true);
object = firstInnerfied.get(second);
System.out.println(object instanceof FirstInner);
//SecondInner,this$2
Field secondInnerfield = third.getClass().getDeclaredField("this$2");
secondInnerfield.setAccessible(true);
object = secondInnerfield.get(third);
System.out.println(object instanceof FirstInner.SecondInner);
}
}
其实用 Java 反编译工具生成内部类可以更加清楚
public class Outer$FirstInner{//FirstInner内部类有一个带外部类参数的构造子
public Outer$FirstInner(Outer paramOuter) {}
....
}
public class Outer$FirstInner$SecondInner{
public Outer$FirstInner$SecondInner(Outer.FirstInner paramFirstInner){}
....
}
public class Outer$FirstInner$SecondInner$ThirdInner{
public Outer$FirstInner$SecondInner$ThirdInner(Outer.FirstInner.SecondInner paramSecondInner){}
}
可见每个内部类都有一个指向所在最近的外部类的一个引用,只不过该引用不需要手动添加,编译器会负责。
关于内部类详细语法可参见帖子:http://119.119.119.8/forum/viewthread.php?tid=1596&page=1&fromuid=247#pid9092