直接看源码吧:
TestInnerClass.java
package com.qihoo.browser.activity;
import android.os.Handler;
import android.os.Message;
public class TestInnerClass {
final MyHandler mH = new MyHandler();
private class MyHandler extends Handler {
public void handleMessage(Message msg) {
handleLaunchActivity();
}
}
private void handleLaunchActivity() {
Log.i("ahking","111");
}
}
编译器对这个类编译后会产生三个.class文件, TestInnerClass.class, TestInnerClass$MyHandler.class 和TestInnerClass$1.class
可见, 编译器对内部类会生成一个独立的class文件.
把这三个class文件用 IntellijIdea 打开看看反编译的结果:
TestInnerClass$MyHandler.class 内部类对应的.class文件
package com.qihoo.browser.activity;
import android.os.Handler;
import android.os.Message;
import com.qihoo.browser.activity.TestInnerClass;
class TestInnerClass$MyHandler extends Handler {
private TestInnerClass$MyHandler(TestInnerClass var1) {
this.this$0 = var1;
}
public void handleMessage(Message msg) {
TestInnerClass.access$100(this.this$0); //源代码: handleLaunchActivity();
}
}
TestInnerClass.class 外部类对应的.class文件
package com.qihoo.browser.activity;
import android.os.Handler;
import android.os.Message;
public class TestInnerClass {
final TestInnerClass.MyHandler mH = new TestInnerClass.MyHandler();
public TestInnerClass() {
}
private void handleLaunchActivity() {
}
private class MyHandler extends Handler {
private MyHandler() {
}
public void handleMessage(Message msg) {
TestInnerClass.this.handleLaunchActivity(); //源代码: handleLaunchActivity();
}
}
}
TestInnerClass$1.class 一个中间的class文件, 对我们并没有实际意义.
package com.qihoo.browser.activity;
// $FF: synthetic class
class TestInnerClass$1 {
}
疑问出来了, 我们并没有找到 TestInnerClass.access$100(this.this$0);的定义, 这是因为IntellijIdea对class文件的反编译结果做了优化,所以没有了access$100的信息. 这个时候就需要借助javap这个原始反编译工具了.
wangxin@wangxin:~/src/browser_6.9.7_forcoopad$ javap -c ./out/production/browser/com/qihoo/browser/activity/TestInnerClass\$MyHandler.class
Compiled from "TestInnerClass.java"
class com.qihoo.browser.activity.TestInnerClass$MyHandler extends android.os.Handler {
final com.qihoo.browser.activity.TestInnerClass this$0;
public void handleMessage(android.os.Message);
Code:
0: aload_0
1: getfield #2 // Field this$0:Lcom/qihoo/browser/activity/TestInnerClass;
4: invokestatic #4 // Method com/qihoo/browser/activity/TestInnerClass.access$100:(Lcom/qihoo/browser/activity/TestInnerClass;)V
7: return
com.qihoo.browser.activity.TestInnerClass$MyHandler(com.qihoo.browser.activity.TestInnerClass, com.qihoo.browser.activity.TestInnerClass$1);
Code:
0: aload_0
1: aload_1
2: invokespecial #1 // Method "<init>":(Lcom/qihoo/browser/activity/TestInnerClass;)V
5: return
}
//可见, 在内部类的handleMessage实现中,通过 invokestatic 调用了外部类的TestInnerClass.access$100方法, 和IntellijIdea给出的结论一致.
wangxin@wangxin:~/src/browser_6.9.7_forcoopad$ javap -c ./out/production/browser/com/qihoo/browser/activity/TestInnerClass.class
Compiled from "TestInnerClass.java"
public class com.qihoo.browser.activity.TestInnerClass {
public com.qihoo.browser.activity.TestInnerClass$MyHandler mH;
public com.qihoo.browser.activity.TestInnerClass();
Code:
0: aload_0
1: invokespecial #2 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #3 // class com/qihoo/browser/activity/TestInnerClass$MyHandler
8: dup
9: aload_0
10: aconst_null
11: invokespecial #4 // Method com/qihoo/browser/activity/TestInnerClass$MyHandler."<init>":(Lcom/qihoo/browser/activity/TestInnerClass;Lcom/qihoo/browser/activity/TestInnerClass$1;)V
14: putfield #5 // Field mH:Lcom/qihoo/browser/activity/TestInnerClass$MyHandler;
17: return
static void access$100(com.qihoo.browser.activity.TestInnerClass);
Code:
0: aload_0
1: invokespecial #1 // Method handleLaunchActivity:()V
4: return
}
//编译器为外部类添加了一个static void access$100()方法, 方法内调用自己的handleLaunchActivity()方法.
另一个就是我们刚才提到的,没啥用的class文件.
wangxin@wangxin:~/src/browser_6.9.7_forcoopad$ javap -c ./out/production/browser/com/qihoo/browser/activity/TestInnerClass\$1.class
Compiled from "TestInnerClass.java"
class com.qihoo.browser.activity.TestInnerClass$1 {
}
打个断点看一下: