匿名类和final外部变量的实现

我们知道,在java中有大量的匿名类使用,而且在匿名类的函数中,我们还可以使用在外部声明的final变量,例如下面的android代码:

public class ArrowPopupWindowDemo extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.arrow_popup_window);

        final Button arrowTop = (Button) findViewById(R.id.arrow_top);
        arrowTop.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                final ListPopupWindow popup = new ListPopupWindow(ArrowPopupWindowDemo.this);
                popup.setAdapter(createAdapter());
                popup.setAnchorView(arrowTop);
                popup.setWidth(400);
                popup.setModal(true);
                popup.setListSelector(getResources().getDrawable(android.R.color.transparent));
                popup.setOnItemClickListener(new AdapterView.OnItemClickListener(){
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        popup.dismiss();
                    }
                });
                ArrowPopupWindow popupWindow = popup.getPopupWindow();
                popupWindow.setTitle(R.string.arrow_top);
                popupWindow.setPositiveButton(android.R.string.ok, null);
                popupWindow.setNegativeButton(android.R.string.cancel, null);
                popup.show();
            }
        });
     }
     .....
}

我们为Button arrowTop创建了一个listner,在内部类的onClick函数中,又使用了arrowTop这个final变量。


我们知道,内部匿名类也是一个单独独立的类,会别java编译器生成一个 <外部类名>$<N>的方式。这个例子里面,就是ArrowPopupWindowDemo$1。我们来反编译它的class,得到如下的信息

Compiled from "ArrowPopupWindowDemo.java"
class com.example.miui.widget.popupwindow.ArrowPopupWindowDemo$1 implements android.view.View$OnClickListener {
  final android.widget.Button val$arrowTop;

  final com.example.miui.widget.popupwindow.ArrowPopupWindowDemo this$0;

  com.example.miui.widget.popupwindow.ArrowPopupWindowDemo$1(com.example.miui.widget.popupwindow.ArrowPopupWindowDemo, android.widget.Button);
    Code:
       0: aload_0       
       1: aload_1       
       2: putfield      #1                  // Field this$0:Lcom/example/miui/widget/popupwindow/ArrowPopupWindowDemo;
       5: aload_0       
       6: aload_2       
       7: putfield      #2                  // Field val$arrowTop:Landroid/widget/Button;
      10: aload_0       
      11: invokespecial #3                  // Method java/lang/Object."<init>":()V
      14: return        
....
根据反编译结果可以看到,java编译生成了两个隐含的域:val$arrowTop和 this$0,对应的就是外部的final arrowTop变量和外部的this变量,而且还为它创建了一个隐含的构造函数。这个构造函数也是隐含调用的,由编译器自动产生。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值