扫码关注官方订阅号
认证0级讲师
这种特性完全是一种语法糖,可以使代码更加精简。要说原因,主要是因为匿名内部类和私有内部类差不多,仅仅只在当前类中使用,所以很多事情在编译时就能确定下来。当startActivity方法在匿名类和外部类中没有冲突时,编译器可以很容易地确定到底该调用哪个类的方法,这时候省略外部类.this没有任何问题。
startActivity
外部类.this
比如下面的代码
public class AnonyNestedClass { public void foo() {} public void bar() { (new Object() { public void foo() {} public void xxx() { foo(); // 这里调用的是匿名类的foo()方法 AnonyNestedClass.this.foo(); // 要想调用外部类的方法必须显式指定路径 } }).xxx(); } }
由于外部类和匿名类都定义了foo()方法,所以默认调用的是匿名类的,如果希望调用外部类的话必须要显式指定调用路径。
foo()
Compiled from "MainActivity.java" class top.ffish.myapp.MainActivity$1 implements android.view.View$OnClickListener { final top.ffish.myapp.MainActivity this$0; top.ffish.myapp.MainActivity$1(top.ffish.myapp.MainActivity); Code: 0: aload_0 1: aload_1 2: putfield #1 // Field this$0:Ltop/ffish/myapp/MainActivity; 5: aload_0 6: invokespecial #2 // Method java/lang/Object."<init>":()V 9: return public void onClick(android.view.View); Code: 0: new #3 // class android/content/Intent 3: dup 4: invokespecial #4 // Method android/content/Intent."<init>":()V 7: astore_2 8: aload_0 9: getfield #1 // Field this$0:Ltop/ffish/myapp/MainActivity; 12: aload_2 13: invokevirtual #5 // Method top/ffish/myapp/MainActivity.startActivity:(Landroid/content/Intent;)V 16: return }
如果你反编译MainActivity$1.class,可以看到这个内部类有一个this$0变量引用MainActivity对象。这个变量在构造器中被初始化(2: putfield指令)也就是说,你不用显示的写MainActivity.this.startActivity(),编译器帮你把这工作给做了
准确说这个问题属于继承关系,startActivity(Intent intent)方法属于Context类下的public方法,Activity继承自Context,自然也会拥有这个方法的使用权,而对于activity来说,这是个activity内的全局方法,只要在作用域内,都是可以直接调用的,默认就是当前activity的context(即activity.this)调用。
原理可以参考http://droidyue.com/blog/2014/10/02/the-private-modifier-in-java/?droid_refer=ninki_posts
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
这种特性完全是一种语法糖,可以使代码更加精简。要说原因,主要是因为匿名内部类和私有内部类差不多,仅仅只在当前类中使用,所以很多事情在编译时就能确定下来。当
startActivity方法在匿名类和外部类中没有冲突时,编译器可以很容易地确定到底该调用哪个类的方法,这时候省略外部类.this没有任何问题。比如下面的代码
由于外部类和匿名类都定义了
foo()方法,所以默认调用的是匿名类的,如果希望调用外部类的话必须要显式指定调用路径。如果你反编译MainActivity$1.class,可以看到这个内部类有一个this$0变量引用MainActivity对象。这个变量在构造器中被初始化(2: putfield指令)
也就是说,你不用显示的写MainActivity.this.startActivity(),编译器帮你把这工作给做了
准确说这个问题属于继承关系,startActivity(Intent intent)方法属于Context类下的public方法,Activity继承自Context,自然也会拥有这个方法的使用权,而对于activity来说,这是个activity内的全局方法,只要在作用域内,都是可以直接调用的,默认就是当前activity的context(即activity.this)调用。
原理可以参考http://droidyue.com/blog/2014/10/02/the-private-modifier-in-java/?droid_refer=ninki_posts